Выдает исключение при отсутствующей перегрузке функции с std :: variable вместо ошибки времени компиляции - PullRequest
0 голосов
/ 06 февраля 2020

Это продолжение до этого вопроса

Рассмотрим следующий код

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

Добавляя все больше и больше типов к числу и потенциально имея функции, которые зависят от на более чем 2 аргументах быстро становится ясно, что мне нужно определить множество функций, а именно все возможные комбинации параметров, которые находятся в std :: варианту.

Однако не все комбинации возможны и / или необходимо. Как я могу определить только нужные мне функции и выдать исключение, если я пытаюсь вызвать функцию, которая не перегружена для конкретной комбинации параметров? Например, допустим, я хочу сохранить только функцию add_ (int, int) или add_ (float, float).

1 Ответ

0 голосов
/ 06 февраля 2020

Я нашел решение с этого сайта

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