Сравните шаблонный тип с определенным классом / типом в C ++ - PullRequest
2 голосов
/ 12 июля 2020

Я пытаюсь найти тип вашего класса, переданного в шаблон как таковой

template<typename ret> 
ret copy(ret var){
    if(ret == int){ //problematic line
       cout << "int" << endl;
    }
    return var;
}

int main()
{
    int a = 5;
    auto b = copy(a);
    cout << b << endl;

    return 0;
}

Но он возвращает ошибку:

main.cpp: In function ‘ret copy(ret)’:
main.cpp:15:12: error: expected primary-expression before ‘==’ token
     if(ret == int){
            ^~
main.cpp:15:15: error: expected primary-expression before ‘int’
     if(ret == int){
               ^~~
main.cpp:15:15: error: expected ‘)’ before ‘int’

Как я могу сделать это правильно ? Спасибо

Ответы [ 2 ]

4 голосов
/ 12 июля 2020

В отличие от python, в C ++ int не является объектом типа class (или чего-то подобного). Вы не можете так сравнивать. Вместо этого вы можете использовать

template<typename ret> 
ret copy(ret var)
{
    if constexpr(std::is_same_v<ret, int>)
    {
        std::cout << "int\n";
    }
    // and so on....

Edit: (в ответ на комментарии yaodav)

Обратите внимание, что if constexpr поддерживается только C ++ 17. Существуют альтернативы, такие как:

    if (std::is_same<ret, int>::value)
    {
        std::cout << "int\n";
    }

, но недостатком является то, что если нужно сделать что-то более сложное с var, например var * 2, то они получат синтаксическую ошибку для * 1016. * типа std::vector<int>. Синтаксис if constexpr не подвержен такого рода ошибкам, поскольку он не пытается скомпилировать код, когда if constexpr ложно (он выполняет только базовый c синтаксический анализ, необходимый для поиска последнего }.

Если нужна более старая версия C ++, тогда единственный жизнеспособный вариант - перегрузка:

void copy_helper(int var) {
    std::cout << "int\n";
}
template <class T>
void copy_helper(const T&) {}

template<typename ret> 
ret copy(ret var)
{
   copy_helper(var);

Также обратите внимание (еще один комментарий yaodav), что использование такой конструкции if является признаком плохой дизайн. В общем, я предпочитаю обусловливать вещи на основе свойств и возможностей, а не на определенных c типах (и мой пример перегрузки выше слишком узкий). Например, если мне нужен интегральный тип (с + , -, *, /, et c.), то я предпочитаю настраивать код на основе наличия этих возможностей.

2 голосов
/ 12 июля 2020

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

Если вы можете использовать информацию о типе времени выполнения, вот возможное решение:

#include <iostream>
#include <typeinfo>

template<typename ret>
ret copy(ret var){
    if(typeid(var) == typeid(int)){
       std::cout << "int" << std::endl;
    }
    return var;
}

int main()
{
    int a = 5;
    auto b = copy(a);
    std::cout << b << std::endl;

    double c = 2.0;
    auto d = copy(c);
    std::cout << d << std::endl;

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...