Search code examples
c++variablestypeoftypeid

How can I compare types in C++?


is there a way to compare types of variables in C++? For example, I want something that works like this: (using pseudolanguage)

template <class T> void checkType(T variable) {
    if(type_of(T) == int) cout << "The variable is of type int.\n";
}

EDIT 1: I tried to use is_same, but it didn't work in Xcode...but when I try to use it in the following simple code in Atom using Script package it runs.

#include <iostream>

using namespace std;

template <class T> void print(T value) {
  if(is_same<T, char> :: value) cout << "char\n";
  if(is_same<T, int> :: value) cout << "int\n";
  if(is_same<T, string> :: value) cout << "string\n";
}

int main() {
  string var1;
  int var2;
  char var3;

  print(var1);
  print(var2);
  print(var3);

  return 0;
}

EDIT 2: I place here the code that doesn't work. Now I tried to comment the part regarding strings and the code works for int and char.

template <class keytype, class attrtype>
void LinkedList <keytype, attrtype> :: insert(keytype k, attrtype a) {
    LinkedList <keytype, attrtype> :: position iter = l.head();
    
    if(is_same<keytype, int> :: value) {
        while(iter != NULL and k > iter -> key) {
            iter = l.next(iter);
        }
        
        l.insert(iter, k, a);
    }
    
    else if(is_same<keytype, char> :: value) {
        while(iter != NULL and tolower(k) > tolower(iter -> key)) {
            iter = l.next(iter);
        }
        
        l.insert(iter, k, a);
    }
     //Whatever type I pass by the template in 'keytype' enters this if statement
    else if(is_same<keytype, string> :: value) {
        bool node_filled = false;
        
        if(iter == NULL) {
            l.insert(iter, k, a);
            node_filled = true;
        }
        else {
            unsigned long rif = 0;
            int i = 0;
            
            while(!node_filled and iter != NULL) {
                if(tolower(iter -> key.at(0)) > tolower(k.at(0))) {
                    l.insert(iter, k, a);
                    node_filled = true;
                }
                else if(tolower(iter -> key.at(0)) < tolower(k.at(0))) {
                    iter = l.next(iter);
                }
                else if(tolower(iter -> key.at(0)) == tolower(k.at(0))) {
                    if(k.size() > iter -> key.size())
                        rif = iter -> key.size();
                    else
                        rif = k.size();
                    
                    while((i < rif - 1) and (k.at(i) == iter -> key.at(i))) {
                        i ++;
                    }
                    
                    if(tolower(iter -> key.at(i)) > tolower(k.at(i))) {
                        l.insert(iter, k, a);
                        node_filled = true;
                    }
                    
                    else if(tolower(iter -> key.at(i)) == tolower(k.at(i))) {
                        if(k.size() < iter -> key.size()) {
                            l.insert(iter, k, a);
                            node_filled = true;
                        }
                        else {
                            iter = l.next(iter);
                        }
                    }
                    
                    else if(tolower(iter -> key.at(i)) < tolower(k.at(i))) {
                        iter = l.next(iter);
                    }
                }
            }
            
            if(!node_filled) {
                l.insert(NULL, k, a);
            }
        }
    }
}

Solution

  • Looking at the code in EDIT 2, you may want to use if constexpr there instead (assuming a C++17-compliant compiler). The issue here is that normally the compiler will need to syntax check your code for all branches of the if statement, even if logically only one branch could possibly be taken for a given template instantiation.

    if constexpr relaxes this requirement: the untaken branch is "discarded", which means that values depending on the template arguments are not instantiated if the branch is not taken. This means that it will never try to do, for example, k.at(0) when keytype is an int, since we will not enter that branch if that is the case.

    Assuming your compiler supports C++17 (and that standard is enabled!), replacing all the if with if constexpr in your code should fix this particular issue.