如何使用访问者调用 lambda 中的 std::visit,访问者是按值捕获的函数对象
How to call std::visit inside a lambda with a visitor that is a function object captured by value
使用访问者(按值捕获的函数对象)在 lambda 中调用 std::visit
似乎并不简单。虽然通过引用捕获工作正常。为什么会这样,是否有可能做到这一点?
我不明白这种情况下的编译错误消息,来自 MSVC 2017:
std::visit': no matching overloaded function found
Failed to specialize function template unknown-type std::visit(_Callable
&&,_Variants &&...)
我假设模板参数推导的行为与仅调用 std::visit
而没有包装调用的 lambda 非常相似。
说明问题的代码:
#include <variant>
struct T {
void operator()(int i) {};
void operator()(float f) {};
};
int main()
{
std::variant<int, float> v = 1;
T t;
// Does not compile.
//auto l1 = [t](auto v) { std::visit(t, v); };
//l1(v);
// Compiles.
auto l2 = [&t](auto v) { std::visit(t, v); };
l2(v);
// Compiles.
std::visit(t, v);
}
lambda 生成的调用运算符标记为 const,因此对于 const 方法,其所有成员也都标记为 const。由于 T 的调用运算符未标记为 const,因此您无法从 lambda 中调用它们。它适用于通过引用捕获的 lambda,因为 const 不会与指针和引用数据成员一起传播。
所以要解决它,您可以将 lambda 标记为可变的,这将使调用运算符不是 const,像您一样通过引用捕获,或者将 T 的调用运算符标记为 const。
使用访问者(按值捕获的函数对象)在 lambda 中调用 std::visit
似乎并不简单。虽然通过引用捕获工作正常。为什么会这样,是否有可能做到这一点?
我不明白这种情况下的编译错误消息,来自 MSVC 2017:
std::visit': no matching overloaded function found
Failed to specialize function template unknown-type std::visit(_Callable &&,_Variants &&...)
我假设模板参数推导的行为与仅调用 std::visit
而没有包装调用的 lambda 非常相似。
说明问题的代码:
#include <variant>
struct T {
void operator()(int i) {};
void operator()(float f) {};
};
int main()
{
std::variant<int, float> v = 1;
T t;
// Does not compile.
//auto l1 = [t](auto v) { std::visit(t, v); };
//l1(v);
// Compiles.
auto l2 = [&t](auto v) { std::visit(t, v); };
l2(v);
// Compiles.
std::visit(t, v);
}
lambda 生成的调用运算符标记为 const,因此对于 const 方法,其所有成员也都标记为 const。由于 T 的调用运算符未标记为 const,因此您无法从 lambda 中调用它们。它适用于通过引用捕获的 lambda,因为 const 不会与指针和引用数据成员一起传播。
所以要解决它,您可以将 lambda 标记为可变的,这将使调用运算符不是 const,像您一样通过引用捕获,或者将 T 的调用运算符标记为 const。