std :: посещение std :: варианта с перегруженной свободной функцией вместо объекта-функции - PullRequest
2 голосов
/ 10 марта 2020

В C ++ 17 есть простой способ для std :: посетить вариант с перегруженной свободной функцией или я должен использовать объект с перегруженным оператором вызова?

Другими словами, это так? Можно добавить что-то простое, чтобы следующая строка компиляции //ERROR! была функционально такой же, как строка //OK!?

#include<variant>
#include<iostream>
#include<list>

#include <boost/hana/functional/overload.hpp>
using boost::hana::overload;

struct A {};
struct B {};

void foo(A) { std::cout << "Got an A!\n"; }
void foo(B) { std::cout << "Got a  B!\n"; }

using AorB = std::variant<A,B>;

constexpr auto foo_obj = overload(
    [](A){std::cout << "Got an A!\n";},
    [](B){std::cout << "Got a  B!\n";});

int main() {

  std::list<AorB> list{A(), B(), A(), A(), B()};

  for (auto& each : list) std::visit(foo, each);      // ERROR!
  for (auto& each : list) std::visit(foo_obj, each);  // OK!

  return 0;
}

Ответы [ 2 ]

6 голосов
/ 10 марта 2020

Вы можете использовать лямбду для обработки перегрузок:

for (auto& each : list) std::visit([](auto e){ return foo(e);}, each);

Демо

1 голос
/ 10 марта 2020

Подумайте о том, что вы здесь делаете: вы называете visit и передаете это "что-то, что можно назвать".

Это всего лишь одно, а не то, «что компилятор может найти с именем foo»

Чтобы реализовать то, что вы запрашиваете, компилятор должен автоматически создать какую-то вещь, содержащую все перегрузки foo, а затем передать его на visit - и это то, что вы делаете с foo_obj

...