gpt4 book ai didi

c++ - 被boost spirit/phoenix/C++11交互搞糊涂了

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:51:42 26 4
gpt4 key购买 nike

我已尽力减少这个问题。

如果我取消注释 void initialize(),那么这段代码可以编译。如果我将其注释掉,那么它就不会构建。

我发现解决此问题的唯一方法是使用 boost::shared_ptr 而不是 std::shared_ptr 在 C++03 模式下构建。

我已经尝试在 OS X Lion(使用 libc++)上使用 stock clang 编译器,在 CentOS 6.4 x64 上使用以下编译器:

/opt/llvm/3.2/bin/clang++ -gcc-toolchain /opt/gcc/4.7.2 -std=gnu++11 foo.cc -I/opt/boost/1.53.0/include -DBOOST_SPIRIT_USE_PHOENIX_V3 -DBOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT -DBOOST_SPIRIT_DEBUG
/opt/llvm/3.1/bin/clang++ -gcc-toolchain /opt/gcc/4.7.2 -std=gnu++11 foo.cc -I/opt/boost/1.53.0/include -DBOOST_SPIRIT_USE_PHOENIX_V3 -DBOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT -DBOOST_SPIRIT_DEBUG
/opt/llvm/3.0/bin/clang++ -gcc-toolchain /opt/gcc/4.7.2 -std=gnu++11 foo.cc -I/opt/boost/1.53.0/include -DBOOST_SPIRIT_USE_PHOENIX_V3 -DBOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT -DBOOST_SPIRIT_DEBUG
/opt/gcc/4.7.2/bin/g++ -std=gnu++11 foo.cc -I/opt/boost/1.53.0/include -DBOOST_SPIRIT_USE_PHOENIX_V3 -DBOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT -DBOOST_SPIRIT_DEBUG
/opt/gcc/4.7.1/bin/g++ -std=gnu++11 foo.cc -I/opt/boost/1.53.0/include -DBOOST_SPIRIT_USE_PHOENIX_V3 -DBOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT -DBOOST_SPIRIT_DEBUG

像往常一样,spirit 的编译器输出非常冗长,所以我将其作为要点包括在内:

代码如下...

#include <boost/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
#include <memory>

class Object {
public:
void initialize(std::vector<int>) {
}

//void initialize() {
//}
};

int main() {
boost::spirit::qi::rule<std::string::iterator, int()> integer;
boost::spirit::qi::rule<std::string::iterator, std::shared_ptr<Object>()> object;

using boost::phoenix::bind;
using boost::spirit::_val;
using boost::spirit::_1;

object
= (*integer) [bind(&Object::initialize, *_val, _1)];
}

最佳答案

#define BOOST_SPIRIT_USE_PHOENIX_V3

为我修复它。并更改 *val只是val因为 phoenix 知道如何将成员函数绑定(bind)到它。


更新 正如@llonesmiz 暗示的那样,事实证明这确实与 ADL 相关。尽管这种关系非常微妙。

  • 一路上的某个地方,std::vector<> 的存在在成员函数指针的 type 中使 ADL 搜索 std 命名空间并找到 std::bind , 而不是 phoenix::bind .
  • 不知何故,当你通过 val , 而不是 *val ,编译器选择凤凰 bind作为更好的匹配。
  • 你可以看到,当你有一个成员函数接受一个 int 时(而不是来自 std 命名空间的类型),问题消失,并且始终选择 phoenix bind。

您可以通过检查 this minimal test program 的输出看到上述观察结果 转储各种绑定(bind)表达式的类型标识(并通过 c++filt 运行它们)



#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/phoenix.hpp>
#include <memory>

class Object {
public:
void initialize(std::vector<int>) {
}
};

int main() {
boost::spirit::qi::rule<std::string::iterator, int()> integer;
boost::spirit::qi::rule<std::string::iterator, std::shared_ptr<Object>()> object;

using boost::phoenix::bind;
using boost::spirit::_val;
using boost::spirit::_1;

object
= (*integer) [bind(&Object::initialize, _val, _1)];
}

关于c++ - 被boost spirit/phoenix/C++11交互搞糊涂了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15326235/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com