Re[8]: std::get(std::variant)
От: rg45 СССР  
Дата: 25.10.25 07:49
Оценка:
Здравствуйте, so5team, Вы писали:

S>Для C++17 у меня получилось что-то вроде: https://godbolt.org/z/YnehMhsT9

S>Но не покидает ощущение, что более продвинутые в современном C++ товарищи смогут сделать проще и компактнее.

Не претендую на звание более продвинутого, но свой вариант предложу, всё-таки:

https://godbolt.org/z/e135r78jY

#include <string>
#include <variant>
#include <iostream>
#include <type_traits>

void has_name_aux(...);
template<typename T> auto has_name_aux(const T& t) -> decltype(t.name);
template<typename T> constexpr bool has_name_v =
    std::is_same_v<std::string, decltype(has_name_aux(std::declval<T>()))>;

template <typename...T>
std::string getName(const std::variant<T...>& v)
{
    return std::visit(
        []<typename X>(X&& x) -> std::string {
            if constexpr(has_name_v<X>)
                return x.name;
            else
                return {};
        }
        , v);
}

int main()
{
    struct a { std::string name{"a"};};
    struct b { };
    struct c { std::string name{"c"};};

    using Variant = std::variant<a, b, c, double>;

    auto test = [](const Variant& v) {
        auto const & name = getName(v);
        std::cout << (name.empty() ? "<<unnamed>>" : name) << '\n';
    };
    test(a{});
    test(b{});
    test(c{});
    test(3.14);
}

a
<<unnamed>>
c
<<unnamed>>
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 25.10.2025 8:13 rg45 . Предыдущая версия . Еще …
Отредактировано 25.10.2025 8:07 rg45 . Предыдущая версия .
Отредактировано 25.10.2025 8:06 rg45 . Предыдущая версия .
Отредактировано 25.10.2025 8:06 rg45 . Предыдущая версия .
Отредактировано 25.10.2025 7:55 rg45 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.