boost::variant 访问者 return 错误(最烦人的解析?)
boost::variant visitor return error (most vexing parse?)
我有一个 boost::variant
object 的 std::array
,我正在尝试创建一个 boost::static_visitor
来访问数组中的一个元素,returning 对每个变体成员类型中的某些内容的引用。太啰嗦了,下面是模仿我的实现的代码片段:
#include <boost/variant.hpp>
#include <array>
struct SomeType {};
struct A {
SomeType something;
SomeType& someMethod() { return something; }
};
struct B {
SomeType something;
SomeType& someMethod() { return something; }
};
struct C {
SomeType something;
SomeType& someMethod() { return something; }
};
typedef boost::variant<A, B, C> MyVariant;
class SomeVisitor : public boost::static_visitor<> {
public:
template<typename T>
SomeType& operator()(T& operand) const {
return operand.someMethod();
}
};
class MyVariants {
public:
SomeType* getSomething(unsigned index);
private:
static const size_t count = 100;
std::array<MyVariant, count> variants_;
};
SomeType* MyVariants::getSomething(unsigned index) {
if(index < count) {
MyVariant& variant = variants_[index];
SomeType& something = boost::apply_visitor(SomeVisitor(), variant);
return &something;
}
else {
return nullptr;
}
}
此片段使用 clang 3.6.2 编译,但 gcc 5.3.1 吐出以下内容(随后是来自 boost 变体的几十个错误 headers)
test.cpp:43:47: error: invalid initialization of non-const reference of type 'SomeType&' from an rvalue of type 'boost::static_visitor<>::result_type {aka void}'
SomeType& something = boost::apply_visitor(SomeVisitor(), variant);
所有错误似乎都在说同样的事情 - 访问者的 return 类型是 void
,我无法将其绑定到 SomeType&
。我不认为我的 SomeVisitor
实现有任何语法错误,因为它可以用 clang 编译得很好。
This question and this question 显示了由 boost::static_visitor
生成的类似错误,并且都由 C++ 的 most-vexing-parse 进行了解释。在这两个问题中,问题都是这样的(使用我上面代码片段中的类型):
MyVariant variant(A());
SomeType& something = boost::apply_visitor(SomeVisitor(), variant);
在这种情况下,我可以理解最令人烦恼的解析是如何应用的。 MyVariant variant(A());
可能对编译器有歧义。我不知道这如何适用于我的代码片段,因为 MyVariant& variant = variants_[index]
看起来很明确。我不知道这些问题是否与我的问题有关。
任何 advice/help 将不胜感激
作为答案提供的评论:
您必须在 static_visitor 的模板参数列表中指定 return 类型。留空就是告诉编译器仿函数将 return void.
class SomeVisitor : public boost::static_visitor<SomeType&> {
public:
template<typename T>
SomeType& operator()(T& operand) const {
return operand.someMethod();
}
};
或者,在使用 c++14 的 boost 的更高版本中:
auto& something = boost::apply_visitor([](auto& x) { return x.someMethod(); },
variant);
我有一个 boost::variant
object 的 std::array
,我正在尝试创建一个 boost::static_visitor
来访问数组中的一个元素,returning 对每个变体成员类型中的某些内容的引用。太啰嗦了,下面是模仿我的实现的代码片段:
#include <boost/variant.hpp>
#include <array>
struct SomeType {};
struct A {
SomeType something;
SomeType& someMethod() { return something; }
};
struct B {
SomeType something;
SomeType& someMethod() { return something; }
};
struct C {
SomeType something;
SomeType& someMethod() { return something; }
};
typedef boost::variant<A, B, C> MyVariant;
class SomeVisitor : public boost::static_visitor<> {
public:
template<typename T>
SomeType& operator()(T& operand) const {
return operand.someMethod();
}
};
class MyVariants {
public:
SomeType* getSomething(unsigned index);
private:
static const size_t count = 100;
std::array<MyVariant, count> variants_;
};
SomeType* MyVariants::getSomething(unsigned index) {
if(index < count) {
MyVariant& variant = variants_[index];
SomeType& something = boost::apply_visitor(SomeVisitor(), variant);
return &something;
}
else {
return nullptr;
}
}
此片段使用 clang 3.6.2 编译,但 gcc 5.3.1 吐出以下内容(随后是来自 boost 变体的几十个错误 headers)
test.cpp:43:47: error: invalid initialization of non-const reference of type 'SomeType&' from an rvalue of type 'boost::static_visitor<>::result_type {aka void}'
SomeType& something = boost::apply_visitor(SomeVisitor(), variant);
所有错误似乎都在说同样的事情 - 访问者的 return 类型是 void
,我无法将其绑定到 SomeType&
。我不认为我的 SomeVisitor
实现有任何语法错误,因为它可以用 clang 编译得很好。
This question and this question 显示了由 boost::static_visitor
生成的类似错误,并且都由 C++ 的 most-vexing-parse 进行了解释。在这两个问题中,问题都是这样的(使用我上面代码片段中的类型):
MyVariant variant(A());
SomeType& something = boost::apply_visitor(SomeVisitor(), variant);
在这种情况下,我可以理解最令人烦恼的解析是如何应用的。 MyVariant variant(A());
可能对编译器有歧义。我不知道这如何适用于我的代码片段,因为 MyVariant& variant = variants_[index]
看起来很明确。我不知道这些问题是否与我的问题有关。
任何 advice/help 将不胜感激
作为答案提供的评论:
您必须在 static_visitor 的模板参数列表中指定 return 类型。留空就是告诉编译器仿函数将 return void.
class SomeVisitor : public boost::static_visitor<SomeType&> {
public:
template<typename T>
SomeType& operator()(T& operand) const {
return operand.someMethod();
}
};
或者,在使用 c++14 的 boost 的更高版本中:
auto& something = boost::apply_visitor([](auto& x) { return x.someMethod(); },
variant);