【问题标题】:Is there a way to call operator function through function pointers?有没有办法通过函数指针调用运算符函数?
【发布时间】:2014-07-31 13:38:06
【问题描述】:

This Q&A 告诉我们不能在 C/C++ 中取消字符串化。例如:

int i = 1 TO_IDENTIFIER("+") 2;

不能扩展到

int i = 1 + 2;

所以我现在正在考虑另一种选择:

保留一个map,将“字符串文字”映射到“运算符函数”,然后调用相应的运算符。

但是我不知道是否有办法将操作函数放入std::map,因为operator+似乎不是一个唯一的变量名称。

这是我遇到的现实问题:

我有一个标记“$1 + $2”,我可以将它们解析为字符串

"$1" "+" "$2"

然后"$1""$2" 被替换为两个类型都是z3::expr 的对象。而且我还需要将"+"替换为声明为的操作函数:

friend z3::expr operator+(z3::expr const & a, z3::expr const & b);

由于还有-<等其他运算符,我希望这可以自动完成。 首先我定义了一个对应于操作符的类型:

typedef z3::expr (*MyOperatorTy)(z3::expr const &a, z3::expr const &b);

然后生成std::unordered_map

  • 在地图中有类型信息:

    std::unordered_map<std::string, MyOperatorTy> strOpMap (
      {"+", z3::expr operator+(z3::expr const & a, z3::expr const & b)},
      ...
    );
    
  • 没有类型信息(就像一个普通的函数变量)

    std::unordered_map<std::string, MyOperatorTy> strOpMap (
      {"+", operator+},
      ...
    );
    

两者都不起作用。我也试过std::function&lt;z3::expr(expr const&amp;, z3::expr const)&gt;作为mapped_type,但还是失败了。

那么有没有什么办法可以把算子函数当作一个变量,通过函数指针调用呢?

【问题讨论】:

  • 在成员函数指针前使用&amp;。为了消除重载的歧义,请强制转换(隐式或显式)。
  • @chris 但是根据cppreference 就像operator+ 一样,对吧?它如何解决我的问题?此外,还有其他运算符需要映射,例如“&&”,所以这些基本功能是不够的。
  • @Yakk 这里没有成员函数;我只是感到困惑如何将运算符功能放入std::unordered_map:-(
  • @HongxuChen 具有固定参数集的运算符函数? static_cast&lt;Signature&gt;(&amp;Namespace::operator+) 假设您将您的类型的 operator+ 放在与您的类型相同的命名空间中(您应该这样做)。所以static_cast&lt; z3::expr(*)(z3::expr const&amp;, z3::exprt const&amp;) &gt;( &amp;z3::operator+ )。至少我认为这应该可行。
  • 谢谢,这似乎是答案。我发现我需要在命名空间 z3 中另外声明 operator+ 为this thread,然后一切正常。

标签: c++ pointers macros z3


【解决方案1】:

&amp;foofoo 表示重载集时会出现问题。而在任何相当大的程序中,operator+ 都会被重载。如果存在使用&amp;foo 允许重载解析的上下文,例如将&amp;foo 分配给具有函数指针类型的变量,则可以解决该问题。然后将该类型用于重载决议。

但是,在您的情况下,您很想填充std::initializer_listoperator+ 的任何重载都可以在该列表中。

幸运的是,另一种情况也允许重载解析:强制转换。所以,

typedef z3::expr (*MyOperatorTy)(z3::expr const &a, z3::expr const &b);

#define STR(var) #var
#define z3Op(var) \
   static_cast<MyOperatorTy> (operator##var## (z3::expr const &a, z3::expr const &b))
#define StrOpPair(var) \
  { STR(var), z3Op(var) }

【讨论】:

  • 感谢您指出我应该使用std::initializer_list。我发现@Yakk 可能是对的。另外, concat operator+ 时似乎存在一些问题;不知道为什么,我加了another question
猜你喜欢
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多