Я реализую посетителя, чтобы использовать его с расширенная библиотека вариантов.
Я хочу знать, правильно ли специализироваться 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.
}
};
Нет проблем, если вы не вернете ссылку на локальную / временную ссылку.
Кроме того, не забудьте проверить достоверность ссылки во времени (она заканчивается, когда разрушается вариантный объект, то есть когда сам вариант уничтожается, или же (!) когда он будет повторно инициализирован).
Вариант содержит объект типа «текущий» элемент, и вы можете ссылка в этот объект прекрасно. Пока вариант не переинициализируется для другого типа элемента (в этом случае ссылка «просто» свисает, точно так же, как если бы закончилось время жизни объекта, на который указывает ссылка).
Так что если 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"}
Видеть это Жить на Колиру также.