1

std::visit使用作为值捕获的函数对象的访问者在 lambda中调用似乎并不简单。不过,通过引用捕获效果很好。为什么会这样,是否有可能做到这一点?

在这种情况下,我不理解来自 MSVC 2017 的编译错误消息:

std::visit': 找不到匹配的重载函数
无法专门化函数模板未知类型 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);

}
4

1 回答 1

5

由 lambda 生成的调用运算符标记为 const,因此对于 const 方法,所有 this 的成员也标记为 const。由于 T 的调用运算符未标记为 const,因此您不能从 lambda 调用它们。它适用于通过引用捕获的 lambda,因为 const 不会通过指针和引用数据成员传播。

因此,要解决它,您可以标记 lambda 可变,这将使调用运算符不是 const,像您一样通过引用捕获,或者标记 T const 的调用运算符。

于 2020-03-04T18:01:49.043 回答