Я хочу написать функцию

template <class Arg>
tuple<int, double> calc(Arg arg);

Возвращает:

[arg,0] if arg is int,
[0,arg] if arg is double 
and [0,0] if arg is nor int or double. 

Я реализую эту функцию, сравнивая тип arg (Arg), тип i (int) и тип d (double) и затем приравнять i = arg или d = arg соответственно. Но если я хочу использовать свою функцию со строкой или другим типом, который не может быть преобразован в int / double, у меня есть ошибка преобразования (это ясно, потому что я не могу приравнять char * к int, например). Как я могу обойти это преобразование const char * в int (или другой неконвертируемый тип в int)? А может есть другая реализация этой функции?

#define GETTYPE(x) typeid(x).name()
template <class Arg>
    tuple<int,double> calc(Arg arg)
    {
        int i = 0;
        double d = 0;
        if (GETTYPE(arg) == GETTYPE(i))
        {
            i = arg;
        }
        else if (GETTYPE(arg) == GETTYPE(d))
        {
            d = arg;
        }
        return make_tuple(i, d);
    }
c++
1
Yauhen Mardan 16 Сен 2018 в 18:59

2 ответа

Лучший ответ

Если вам не нужен код C ++ 17, вы можете использовать перегрузку

tuple<int, double> foo(int a) {
    return {a, 0.0};
}

tuple<int, double> foo(double a) {
    return {0, a};
}

template<typename T>
tuple<int, double> foo(T) {
    return {0, 0.0};
}

Если вам нужен код C ++ 17:

template<typename T>
tuple<int, double> foo([[maybe_unused]] T a) {
    if constexpr (std::is_same_v<int, T>)
        return {a, 0.0};

    else if constexpr (std::is_same_v<double, T>)
        return {0, a};

    else
        return {0, 0.0};
}
4
Antoine Morrier 16 Сен 2018 в 18:56

Самое простое решение - иметь 3 отдельных перегрузки:

tuple<int, double> calc(int arg)
{
  return make_tuple(arg, 0.);
}

tuple<int, double> calc(double arg)
{
  return make_tuple(0, arg);
}

template < typename T >
tuple<int, double> calc(T arg)
{
  return make_tuple(0, 0.);
}

В качестве альтернативы вы можете использовать специализации шаблонов:

template < typename T >
tuple<int, double> calc(T arg)
{
  return make_tuple(0, 0.);
}

template <>
tuple<int, double> calc< int >(int arg)
{
  return make_tuple(arg, 0.);
}

template <>
tuple<int, double> calc< double >(double arg)
{
  return make_tuple(0, arg);
}
1
Alan Birtles 16 Сен 2018 в 16:09