Информация об изменениях

Сообщение Re[4]: Вариадики и std::visit от 29.10.2020 13:30

Изменено 29.10.2020 14:14 SaZ

Re[4]: Вариадики и std::visit
Здравствуйте, johny5, Вы писали:


C>>>
C>>>// from https://en.cppreference.com/w/cpp/utility/variant/visit
C>>>template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
C>>>template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

C>>>template<typename ...Args>
C>>>std::shared_ptr<IFace> factory(const Var& v)
C>>>{
C>>>    ....
C>>>    std::visit( overloaded{
C>>>         [&p]( typename Args::Key key ) 
C>>>         { 
C>>>            p = std::make_shared<Args>(key);
C>>>         } ...
C>>>    }, v); 
C>>>    ...
C>>>}
C>>>


J>Хм, кто сможет объяснить как это компилируется? В частности волнуют записи overloaded(Ts...) и overloaded{


Я сначала тоже не вдуплял
Посмотрите пример по ссылке — https://en.cppreference.com/w/cpp/utility/variant/visit.
У меня тоже самое, только на вариадиках.
    for (auto& v: vec) {
        // 4. another type-matching visitor: a class with 3 overloaded operator()'s
        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);
    }


Это всё раскрывается в такой псевдокод, через вариадики:
struct overloaded
{
  operator()(auto arg)
  {
    [](auto arg) { std::cout << arg << ' '; }(arg);
  }
  operator()(double arg)
  {
    [](double arg) { std::cout << std::fixed << arg << ' '; }(arg);
  }
  operator()(const std::string& arg)
  {
    [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; }(arg);
  }
}


std::visit просто не умеет принимать на вход массив лямбд, вот они и заворачивается в функтор с перегруженными скобочками, который уже понятен для std::visit.
Re[4]: Вариадики и std::visit
Здравствуйте, johny5, Вы писали:


C>>>
C>>>// from https://en.cppreference.com/w/cpp/utility/variant/visit
C>>>template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
C>>>template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

C>>>template<typename ...Args>
C>>>std::shared_ptr<IFace> factory(const Var& v)
C>>>{
C>>>    ....
C>>>    std::visit( overloaded{
C>>>         [&p]( typename Args::Key key ) 
C>>>         { 
C>>>            p = std::make_shared<Args>(key);
C>>>         } ...
C>>>    }, v); 
C>>>    ...
C>>>}
C>>>


J>Хм, кто сможет объяснить как это компилируется? В частности волнуют записи overloaded(Ts...) и overloaded{


Я сначала тоже не вдуплял
Посмотрите пример по ссылке — https://en.cppreference.com/w/cpp/utility/variant/visit.
У меня тоже самое, только на вариадиках.
    for (auto& v: vec) {
        // 4. another type-matching visitor: a class with 3 overloaded operator()'s
        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);
    }


Это всё раскрывается в такой псевдокод, через перегрузку оператора() и вариадики:
struct overloaded
{
  operator()(auto arg)
  {
    [](auto arg) { std::cout << arg << ' '; }(arg);
  }
  operator()(double arg)
  {
    [](double arg) { std::cout << std::fixed << arg << ' '; }(arg);
  }
  operator()(const std::string& arg)
  {
    [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; }(arg);
  }
}


std::visit просто не умеет принимать на вход массив лямбд, вот они и заворачивается в функтор с перегруженными скобочками, который уже понятен для std::visit.