我已尽我所能减少这个问题。
如果我取消注释void initialize(),那么这段代码将编译。如果我忽略了它,那么它就不会构建。
解决这个问题的唯一方法是用C++03模式构建boost::shared_ptr而不是std::shared_ptr。
我尝试使用on上的stock编译器(使用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与往常一样,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)];
}发布于 2013-03-10 19:08:17
#define BOOST_SPIRIT_USE_PHOENIX_V3帮我修好。并将*val更改为val,因为菲尼克斯将知道如何将成员函数绑定到它。
正如@llonesmiz所暗示的那样,更新了,这实际上与ADL有关。虽然这种关系非常微妙。
std::vector<>在成员函数指针类型中的存在使得ADL搜索std名称空间并找到std::bind,而不是phoenix::bind。val而不是*val时,编译器会选择菲尼克斯bind作为更好的匹配。int (而不是来自std命名空间的类型)时,问题就消失了,并且总是选择菲尼克斯绑定。您可以通过检查这个最小的测试程序的输出来查看上面的观察,该输出转储各种绑定表达式的类型(并通过c++filt运行它们)。
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)];
}https://stackoverflow.com/questions/15326235
复制相似问题