Throw exception on missing function overload with std::variant instead of compile time error

笑着哭i 提交于 2020-05-17 07:20:06

问题


This is a follow up to this question

Consider the following code

#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);
}

By adding more and more types to number and potentially having function that depend on more than 2 arguments, it quickly becomes clear, that I need to define a lot of functions, namely all possible parameter combinations that are found in the std::variant.

However, not all combinations are possible and/or needed. How can I only define the functions I need and throw an exception if I try to call a function that is not overloaded for the particular parameter combination? For example, let's say I only want to keep the add_(int, int) or add_(float, float) function.


回答1:


I found a solution from 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
    );
}


来源:https://stackoverflow.com/questions/60086331/throw-exception-on-missing-function-overload-with-stdvariant-instead-of-compil

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!