c++ - boost::variant 访问者返回错误(最烦人的解析?)

标签 c++ c++11 gcc boost boost-variant

我有一个 boost::variant 对象的 std::array,我正在尝试创建一个 boost::static_visitor它访问数组中的一个元素,返回对每个变体成员类型中的某些内容的引用。太啰嗦了,下面是模仿我的实现的代码片段:

#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 变体 header 的几十个错误)

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);

所有错误似乎都在表达同一件事 - 访问者的返回类型是 void,我无法将其绑定(bind)到 SomeType&。我认为我的 SomeVisitor 实现没有任何语法错误,因为它可以用 clang 编译。

This questionthis question显示由 boost::static_visitor 生成的类似错误,并且两者都由 C++ 最令人烦恼的解析器解释。在这两个问题中,问题都是这样的(使用我上面代码片段中的类型):

MyVariant variant(A());
SomeType& something = boost::apply_visitor(SomeVisitor(), variant);

在这种情况下,我可以理解最令人烦恼的解析是如何应用的。 MyVariant variant(A()); 可能对编译器有歧义。不过,我不知道这如何适用于我的代码片段,因为 MyVariant& variant = variants_[index] 看起来非常明确。我不知道这些问题是否与我的问题有关。

任何建议/帮助将不胜感激

最佳答案

作为答案提供的评论:

您必须在 static_visitor 的模板参数列表中指定返回类型。将其留空就是告诉编译器仿函数将返回 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);

关于c++ - boost::variant 访问者返回错误(最烦人的解析?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36345388/

相关文章:

C++ 异常、GCC 和 "inline-functions"标志

c++ - C++中的多个构造函数

C++ 数组通过引用传递,但是这个怎么理解呢?

c++ - 如何设置依赖于其他参数的参数默认值?

c++ - const 左值 (const T&) 和右值 (T&&) 重载的共享实现 : just like what is done for const and non-const overloads

c - 带有 gcc 的裸机 ARM 上的 RAM 和 ROM 部分之间的 long_calls

C++ 多拷贝赋值运算符

c++ - 构造函数泄漏

c++ - 如果使用 remove_if 如何删除 vector 的空单元格

c++ - fread() 调用后的段错误