有什么方法可以在std :: visit中跳过变量类型的一些重载组合?

fen*_*fen 6 c++ c++17

std::visit支持多种输入变体.但是,代码应该处理来自这些变体的所有类型的组合.

有没有办法跳过不"有意义"的组合?

例如:

template<class... Ts> 
struct overloaded : Ts... { using Ts::operator()...; };

template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

int main() {
    std::variant<int, float, char> v1 { 's' };
    std::variant<int, float, char> v2 { 10 };

    std::visit(overloaded{
        [](int a, int b) { },
        [](int a, float b) { },
        [](int a, char b) { },
        [](float a, int b) { },
        [](float a, float b) { },
        [](float a, char b) { },
        [](char a, int b) { },
        [](char a, float b) { },
        [](char a, char b) { }
    }, v1, v2);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

是否有机会只实施几个重要的组合,并"留下"其余的组合?(当然,如果您忘记实现一个组合,编译器将报告令人讨厌的错误...)

也许是普通的lambdas?

std::visit(overloaded{
        [](int a, int b) { },
        [](int a, float b) { },
        [](int a, char b) { },
        [](float a, int b) { },
        [](auto a, auto b) { }, // <<
    }, v1, v2);
Run Code Online (Sandbox Code Playgroud)

这有效,但我想知道是否有更好的解决方案?

更新:这里是答案中提到的解决方案的游乐场:http: //coliru.stacked-crooked.com/a/78d9f2f25789bad2

bol*_*lov 7

是的,通用lambda是一个非常好的解决方案.您提出的解决方案实际上适用于广告litteram.

通常的过载规则适用.

[](auto a, auto b)
Run Code Online (Sandbox Code Playgroud)

在这个意义上是等同的

template <class T1, class T2> auto foo(T1 a, T2 b) const;
Run Code Online (Sandbox Code Playgroud)

任何与非模板化重载完全不匹配的东西都将调用泛型lambda.

您可以通过提供类似有点混为一谈[] (int a, auto b)[] (auto a, auto b).仍然适用通常的过载规则.

或者更混合[]<class T>(T a, T b)(从C++ 20开始)

  • @是的.我想如果有任何陷阱.通常的问题是隐式转换将转到模板,但它不适用于她,因为你在`std :: variant`中有一个清晰的类型.所以,是的,它可以作为例外(据我所知). (2认同)