Правильна ли эта реализация посетителя?

Я реализую посетителя, чтобы использовать его с расширенная библиотека вариантов.
Я хочу знать, правильно ли специализироваться boost::static_visitor<> с константным ссылочным типом.

Обратите внимание, что мой вопрос здесь следующий:

Есть какие-то проблемы со специализацией boost::static_visitor<> в boost::static_visitor<const T&> ?

template<typename T>
struct my_visitor : public boost::static_visitor<const T&> {

template<typename U> const T& operator()(U& u) const {
// some code here .....
return X<U>::get_some_t(); // finally return some T.
}
};

2

Решение

Нет проблем, если вы не вернете ссылку на локальную / временную ссылку.

Кроме того, не забудьте проверить достоверность ссылки во времени (она заканчивается, когда разрушается вариантный объект, то есть когда сам вариант уничтожается, или же (!) когда он будет повторно инициализирован).

Предпосылки и объяснение

Вариант содержит объект типа «текущий» элемент, и вы можете ссылка в этот объект прекрасно. Пока вариант не переинициализируется для другого типа элемента (в этом случае ссылка «просто» свисает, точно так же, как если бы закончилось время жизни объекта, на который указывает ссылка).

Так что если get_somet_t() возвращает T& или же T const& (или что-то с подходящим неявным преобразованием) проблем нет.

В более простой настройке позвольте мне продемонстрировать допустимые параметры:

variant<int, std::string> v1 = 42;

int& i1 = get<int>(v1); // returns by ref, valid
i1 *= 2;

// now v1 contains the updated integer value 84

Кроме того, вы можете даже сделать варианты / просто ссылки /:

std::string s = "hello";
int answer = 42;

variant<int&, std::string&> v2(s);
get<std::string&>(v2) += " world"; // now s contains "hello world"
variant<int&, std::string&> v3(answer);
get<int&>(v3) *= 2; // now `answer` contains 84

Увидеть все Жить на Колиру


демонстрация

Положил еще один способ, следующее хорошо:

struct A { std::string a_property; };
struct B { std::string b_field;    };

struct select_member : static_visitor<std::string&> {
std::string& operator()(A& a) const { return a.a_property; }
std::string& operator()(B& b) const { return b.b_field;    }
};

int main()
{
variant<A,B> v = A { "some string" };

apply_visitor(select_member(), v) += " suffix";

std::cout << get<A>(v).a_property << "\n"; // prints "some string suffix"}

Видеть это Жить на Колиру также.

2

Другие решения


По вопросам рекламы [email protected]