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
是的,通用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开始)