Здравствуйте, Marty, Вы писали:
M>у нас намечается простыня
Это у вас намечается
if constexpr(std::is_same_v(t, typeA) || std::is_same_v(t, typeB))
{
}
M>А как мне выйти из функции, которая вызывает std::visit, по какой-нибудь альтернативе?
Не распарсил.
M>Ещё бесит, что в visit значение варианта передаётся после обработчика. Почему нельзя было его первым аргументом? Оно за портянкой лямбды теряется совсем
Ну, у меня это единственная претензия к std::visit.
Здравствуйте, landerhigh, Вы писали:
M>>Ещё бесит, что в visit значение варианта передаётся после обработчика. Почему нельзя было его первым аргументом? Оно за портянкой лямбды теряется совсем
L>Ну, у меня это единственная претензия к std::visit.
Ну, почему в std::visit так сделано, понятно — потому что там это не единичное значение, а вариадик. А для одного значения действительно удобнее, когда сначала идет вариант, а за ним обработчики. Вот поэтому я и делаю обычно несложную обертку вокруг std::visit, типа как показано здесь
. А заодно это обертка включает в себя и overloaded, и использующий код получается аккуратным и очищенным от лишних технических подробностей, типа как здесь
Здравствуйте, Marty, Вы писали:
M>ЗЫ А в частном порядке нельзя с тобой связаться, если ты не против? А то код проекта не могу показывать на публику, но в частном порядке думаю можно. А ты бы мог без труда найти дерьмовые решения, и показать на форуме только их, чтобы всем было полезно.
Я смотрю, здесь уже накидали рабочих примеров, так что мне и добавить особо нечего. Дальше уже эту идею можно развивать в прикладной области с использованием концептов/констрейнтов и с добавлением синтаксического сахара
Здравствуйте, so5team, Вы писали:
YV>>>здесь
M>>Спасибо, поизучаю. Но я бы не сказал, что это всё очень просто
S>ИМХО, вот так гораздо проще: https://godbolt.org/z/YW839hjGY S>Но идея та же самая.
Спс.
Правда, я пока на 17ом стандарте, и ещё вопрос, насколько это смогут поддерживать сишники
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, so5team, Вы писали:
YV>>>>здесь
M>>>Спасибо, поизучаю. Но я бы не сказал, что это всё очень просто
S>>ИМХО, вот так гораздо проще: https://godbolt.org/z/YW839hjGY S>>Но идея та же самая.
M>Спс.
M>Правда, я пока на 17ом стандарте
Для C++17 у меня получилось что-то вроде: https://godbolt.org/z/YnehMhsT9
Но не покидает ощущение, что более продвинутые в современном C++ товарищи смогут сделать проще и компактнее.
M>и ещё вопрос, насколько это смогут поддерживать сишники
Здравствуйте, so5team, Вы писали:
S>Для C++17 у меня получилось что-то вроде: https://godbolt.org/z/YnehMhsT9 S>Но не покидает ощущение, что более продвинутые в современном C++ товарищи смогут сделать проще и компактнее.
Не претендую на звание более продвинутого, но свой вариант предложу, всё-таки:
Еще один вариант: перенос специализации c операторов () визитора, на специализацию свободных функций:
struct a { std::string name{"a"};};
struct b { };
struct c { std::string name{"c"};};
struct d { };
using Variant = std::variant<a, b, c, d>;
template<typename T>
auto getName(const T& v) -> decltype(v.name) { return v.name; } // можнос специализировать типы по наличию поляinline std::string getName(const d& v) { return"type d"; } // можнос специализировать конкретные типы
// Все варианты типов, что не подошли под спефиализации. Наименее приоритетный вариант.inline std::string getName(...) { return""; }
template<typename ...T>
std::string getName(const std::variant<T...>& v) // Работа с variant обязательно шаблонная. Иначе можно попасть в рекурсивный вызов для не специализированного класса.
{
return std::visit( [](const auto& vi)->std::string { return getName(vi); }, v );
}
Плюсы:
В случае, когда конкретный тип заранее известен, будет сразу вызваны функции для конкретных типов, избегая диспетчеризации в visit.
Можно писать код в "распределенном" режиме, определяя getName для новых классов рядом с классом.
с++17 — достаточно. Можно и на c++11, но специализация по признаку наличия поля — сильно многословнее.
Здравствуйте, Chorkov, Вы писали:
C>Плюсы: C>В случае, когда конкретный тип заренее известве, буджут сразу вызваны функции для конкретных типов, избегая диспетчеризации в visit.
Ещё один плюс — подключается ADL. Это значит, что getName становится тем, что в стандартной библиотеке обозначается как customization point.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Marty, Вы писали:
M>Или вот вот такой пример. Есть variant с парой десятков альтернатив. У половины альтернатив есть атрибут name, у других нет. Я хочу функцию, которая возвращает name, если он есть, или пустую строку, если его нет. Чтобы выше не парится, выписывая везде std::visit для получения этого атрибута.