使用 std::variant 而不是编译时错误在缺少函数重载时抛出异常
Throw exception on missing function overload with std::variant instead of compile time error
这是
的跟进
考虑以下代码
#include <variant>
int add_(int a, int b){
return a+b;
}
float add_(float a, float b){
return a+b;
}
float add_(int a, float b){
return a+b;
}
float add_(float a, int b){
return a+b;
}
using Number = std::variant<int, float>;
Number add(Number const& lhs, Number const& rhs ){
return std::visit( []( auto& lhs_, auto& rhs_ )->Number { return {add_( lhs_, rhs_ )}; }, lhs, rhs );
}
int main(){
Number a = 1.f;
Number b = 2.f;
Number c = add(a, b);
}
通过向 number 添加越来越多的类型并可能具有依赖于 2 个以上参数的函数,很快就会变得很清楚,我需要定义很多函数,即在std::variant.
但是,并非所有组合都是可能的 and/or 需要。如果我尝试调用一个没有为特定参数组合重载的函数,我如何才能只定义我需要的函数并抛出异常?例如,假设我只想保留 add_(int, int) 或 add_(float, float) 函数。
我从 this site
找到了解决方案
template <class ...Fs>
struct overload : Fs... {
overload(Fs const&... fs) : Fs{fs}...
{}
using Fs::operator()...;
};
Number add(const Number& arg0, const Number& arg1){
return std::visit(
overload{
[](int a, int b) -> Number{return add_(a, b);}
,[](float a, float b) -> Number{return add_(a, b);}
,[](auto& a, auto& b) -> Number{throw std::runtime_error("unsupported parameter combination");}
},
arg0, arg1
);
}
这是
考虑以下代码
#include <variant>
int add_(int a, int b){
return a+b;
}
float add_(float a, float b){
return a+b;
}
float add_(int a, float b){
return a+b;
}
float add_(float a, int b){
return a+b;
}
using Number = std::variant<int, float>;
Number add(Number const& lhs, Number const& rhs ){
return std::visit( []( auto& lhs_, auto& rhs_ )->Number { return {add_( lhs_, rhs_ )}; }, lhs, rhs );
}
int main(){
Number a = 1.f;
Number b = 2.f;
Number c = add(a, b);
}
通过向 number 添加越来越多的类型并可能具有依赖于 2 个以上参数的函数,很快就会变得很清楚,我需要定义很多函数,即在std::variant.
但是,并非所有组合都是可能的 and/or 需要。如果我尝试调用一个没有为特定参数组合重载的函数,我如何才能只定义我需要的函数并抛出异常?例如,假设我只想保留 add_(int, int) 或 add_(float, float) 函数。
我从 this site
找到了解决方案template <class ...Fs>
struct overload : Fs... {
overload(Fs const&... fs) : Fs{fs}...
{}
using Fs::operator()...;
};
Number add(const Number& arg0, const Number& arg1){
return std::visit(
overload{
[](int a, int b) -> Number{return add_(a, b);}
,[](float a, float b) -> Number{return add_(a, b);}
,[](auto& a, auto& b) -> Number{throw std::runtime_error("unsupported parameter combination");}
},
arg0, arg1
);
}