cpp функция, которая возвращает значение в зависимости от типа шаблона - PullRequest
0 голосов
/ 09 апреля 2020

Я хотел бы преобразовать следующий псевдокод в код c ++ 17:

template<class T>
char* foo(){
    if(T is a float) return "we have a float"
    if(T is a int) return "we have a int"
    if(T is a double) return "we have a double"
    return "unknown"
}

Чтобы я мог использовать его как

LOGD("%s", foo<float>());
LOGD("%s" foo<double>());

Возможно ли это?

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

Вы можете использовать std::is_same для проверки типов, и поскольку вы упомянули C ++ 17, вы можете использовать constexpr, если , который проверяет условие во время компиляции, и в соответствии с результатом оператор true / false будет отброшен.

template<class T>
const char* foo(){
    if constexpr (std::is_same_v<T, float>) return "we have a float";
    else if constexpr (std::is_same_v<T, int>) return "we have a int";
    else if constexpr (std::is_same_v<T, double>) return "we have a double";
    else return "unknown";
}

До C ++ 17 вы также можете использовать original if, и условие будет проверено во время выполнения.

Кстати: строковый литерал стиля c имеет тип const char[] и не может быть преобразован char* начиная с C ++ 11, поэтому лучше изменить тип возвращаемого значения до const char*.

1 голос
/ 09 апреля 2020

Я бы использовал обобщенный класс c для содержания сообщения:

template <class T> struct message { static const char * const value; };

template <> 
constexpr const char *message<int>::value = "we have an int";

template <class T>
const char *foo() { return message<T>::value; }

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

template <> 
constexpr const char *message<float>::value = "we have a float";

См. https://gcc.godbolt.org/z/_mhHwI

...