使用 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
    );
}