简体   繁体   中英

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM