我尽力减少这个问题。
如果我取消注释void initialize()
,则此代码会编译。如果我把它留下来注释掉,那就不会构建。
我找到解决此问题的唯一方法是使用boost::shared_ptr
而不是std::shared_ptr
构建C ++ 03模式。
我尝试使用OS X Lion上的stock clang编译器(使用libc ++)和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
像往常一样,精神的编译器输出非常冗长,所以我把它作为一个要点包含在内:
#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)];
}
答案 0 :(得分:2)
#define BOOST_SPIRIT_USE_PHOENIX_V3
为我修复它。并将*val
更改为val
因为phoenix将知道如何将成员函数绑定到它。
更新正如@llonesmiz暗示的那样,事实证明这与ADL有关。虽然这种关系非常微妙。
std::vector<>
的存在使得ADL搜索std命名空间并找到std::bind
,而不是phoenix::bind
。 val
而不是*val
时,编译器会选择凤凰bind
作为更好的匹配。int
(而不是std
命名空间中的类型),问题就会消失,并且总是选择phoenix bind。 您可以通过检查转储各种绑定表达式的类型ID的 this minimal test program 的输出来查看上述观察结果(并通过c++filt
运行它们)
更新 Clang似乎只喜欢使用boost::shared_ptr
: http://liveworkspace.org/code/idDtv$3 。我只能假设这是由于libc ++差异(?)
#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)];
}