2016-03-31 1 views
1

У меня есть std::array объекта boost::variant, и я пытаюсь создать boost::static_visitor, который посещает элемент в массиве, возвращая ссылку на что-то в каждом из вариантные типы элементов. Это полный рот, так вот фрагмент кода имитируя моя реализация:boost :: variant visitor return error (most vexing parse?)

#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; 
    } 
} 

Этот фрагмент кода компилирует с лязгом 3.6.2, но GCC 5.3.1 выплевывает следующее (а затем несколько десятков ошибок от подталкивание вариантов заголовков)

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, и я не могу связать, что к SomeType&. Я не думаю, что есть синтаксические ошибки с моей реализацией SomeVisitor, так как это компилирует отлично с clang.

This question и this question показать похожие ошибки, сгенерированные boost::static_visitor, и оба они были объяснены наиболее-досадным анализом C++. В обеих этих вопросах, вопрос был что-то вроде этого (с помощью типов из моего фрагмента выше):

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

В этом контексте, я могу понять, как применяется наиболее раздражающий синтаксический анализ. MyVariant variant(A()); может быть неоднозначным для компилятора. Я не знаю, как это относится к моему фрагменту, поскольку MyVariant& variant = variants_[index] кажется довольно явным. Я не знаю, связаны ли эти вопросы с моими проблемами.

Любые советы/помощи был бы оценен

+2

Вы должны указать тип возвращаемого значения в списке аргументов шаблона static_visitor в. Если оставить его пустым, он сообщает компилятору, что функтор вернет пустоту. –

+0

Спасибо! Это была проблема. Я сделал «boost :: static_visitor» с возвращаемым значением несколько недель назад (с правильным синтаксисом), поэтому я вдвойне смущен –

+0

Мы все это сделали. Обратите внимание, что в более поздних версиях boost с C++ 14 вам не нужен статический посетитель. Будет достаточно лямбда с типом 'auto &'. –

ответ

1

комментария при условии, как ответ:

Вы должны указать тип возвращаемого значения в списке аргументов шаблона static_visitor в. Если оставить его пустым, он сообщает компилятору, что функтор вернет пустоту.

class SomeVisitor : public boost::static_visitor<SomeType&> { 
public: 
    template<typename T> 
    SomeType& operator()(T& operand) const { 
    return operand.someMethod(); 
    } 
}; 

В качестве альтернативы, в более поздних версиях импульс с C++ 14:

auto& something = boost::apply_visitor([](auto& x) { return x.someMethod(); }, 
             variant); 
Смежные вопросы