Откуда этот тип наследует эта структура?

Так этот пример от: http://en.cppreference.com/w/cpp/utility/variant/visit объявляет специализированный тип:

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

Который построен здесь как r-значение:

std::visit(overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
}, v);

Я пытаюсь понять, как это работает. Какого типа это overloaded наследует отсюда? Это похоже на массив лямбд, но я не вижу, как это operator(), Может кто-нибудь объяснить, как здесь работает наследство?

5

Решение

overloaded наследуется от каждой лямбды индивидуально, и у каждой лямбды есть оператор вызова. Поэтому вы создаете структуру, в которой все операторы вызова находятся в одном наборе перегрузки. Пока они не являются двусмысленными, правильный будет автоматически выбран.

Вы можете представить себе шаблон вариации для расширения до

struct overloaded :
// inherits from
decltype([](auto arg) { std::cout << arg << ' '; }),
decltype([](double arg) { std::cout << std::fixed << arg << ' '; }),
decltype([](const std::string& arg) { std::cout << std::quoted(arg) << ' '; })

// has three operator()s
{
using decltype([](auto arg) { std::cout << arg << ' '; })::operator();
using decltype([](double arg) { std::cout << std::fixed << arg << ' '; })::operator();
using decltype([](const std::string& arg) { std::cout << std::quoted(arg) << ' '; })::operator();
};

За исключением реального кода, это не сработает, потому что лямбды с одинаковым телом все равно будут иметь разные типы.

Это создает 1 overloaded тип с множественным наследованием для каждого экземпляра.

6

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

Других решений пока нет …

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