std::visit 具有重载自由函数而不是函数对象的 std::variant
std::visit a std::variant with overloaded free-function instead of function-object
在 C++17 中,是否有一种简单的方法来 std::visit 具有重载自由函数的变体,或者我必须使用具有重载调用运算符的对象?
换句话说,是否可以添加一些简单的东西来使下面的 //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;
}
想想你在这里做什么:你调用 visit
并传递它 "something that can be called"。
那只是一个东西,不是"whatever the compiler can find named foo
"
为了实现你所要求的,编译器必须自动构建某种包含 foo 的所有重载的东西,然后将它传递给 visit
- 这就是你正在做的foo_obj
您可以使用 lambda 来处理重载:
for (auto& each : list) std::visit([](auto e){ return foo(e);}, each);
在 C++17 中,是否有一种简单的方法来 std::visit 具有重载自由函数的变体,或者我必须使用具有重载调用运算符的对象?
换句话说,是否可以添加一些简单的东西来使下面的 //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;
}
想想你在这里做什么:你调用 visit
并传递它 "something that can be called"。
那只是一个东西,不是"whatever the compiler can find named foo
"
为了实现你所要求的,编译器必须自动构建某种包含 foo 的所有重载的东西,然后将它传递给 visit
- 这就是你正在做的foo_obj
您可以使用 lambda 来处理重载:
for (auto& each : list) std::visit([](auto e){ return foo(e);}, each);