# C++ C++, comparing type <T> to integer

## Recommended Posts

Good Morning Everyone,

I have a simple question.

Is it possible to compare a generic template< class T > to an integer? For example...


template < class T >
void foo(){
int value = 2;
if( T == 2 ){//this is the comperator i am wondering about
do something...
}
}

Thanks so much again,

Mike

##### Share on other sites
Posted (edited)

I think that will work as long as T has a non explicit T(int) constructor AND a bool operartor==(const T&) exists, the 2 in (T == 2) will be casted into a T and the const T& operator will be called, so the check will not be between ints but between T's. This is how duck typing works in templates.

Also I take it this is pseudocode because you cannot do (T==2), that would be equivalent to say (int == 2) and won't compile, however (typeid(T).hash_code()==typeid(int).hash_code()) will.

So the correct code would be something like this:

template < class T >
void foo(T t){
if( t == 2 ){
do something...
}
}

OR

template < class T >
void foo(const T& t){
if( t == 2 ){
do something...
}
}

Edited by Kwizatz

##### Share on other sites
Posted (edited)

It would work if T were an integer type. As is though, I think you'd need to clarify what it would mean for a type to be equal to an integer.

[Edit: To be clear, by 'integer type' I mean an integer template parameter, not just that T itself is an integer type.]

Edited by Zakwayda

##### Share on other sites
Posted (edited)

I think you would have to use   "template< int T>" . As it stands T expects a typename, which I don't see how you can compare to an integer value.  It would kind of be like saying saying "int == 2".

Edited by Gnollrunner

##### Share on other sites
7 hours ago, Gnollrunner said:

I think you would have to use   "template< int T>" . As it stands T expects a typename, which I don't see how you can compare to an integer value.  It would kind of be like saying saying "int == 2".

You can do that or you can do it like @Kwizatz

##### Share on other sites
4 hours ago, ChaosEngine said:

You can do that or you can do it like @Kwizatz

Yes of course. I'm just saying if you're comparing T itself it has to be a value.

##### Share on other sites
21 hours ago, Kwizatz said:

I think that will work as long as T has a non explicit T(int) constructor AND a bool operartor==(const T&) exists, the 2 in (T == 2) will be casted into a T and the const T& operator will be called, so the check will not be between ints but between T's. This is how duck typing works in templates.

Also I take it this is pseudocode because you cannot do (T==2), that would be equivalent to say (int == 2) and won't compile, however (typeid(T).hash_code()==typeid(int).hash_code()) will.

So the correct code would be something like this:


template < class T >
void foo(T t){
if( t == 2 ){
do something...
}
}

OR

template < class T >
void foo(const T& t){
if( t == 2 ){
do something...
}
}

Yes it's just a quick piece of pseudo code, you are correct and your code example is what I meant.

##### Share on other sites
On 4/3/2019 at 7:33 PM, Kwizatz said:

I think that will work as long as T has a non explicit T(int) constructor AND a bool operartor==(const T&) exists, the 2 in (T == 2) will be casted into a T and the const T& operator will be called, so the check will not be between ints but between T's. This is how duck typing works in templates.

There could also be an operator== defined for (const T&, int), so that it can be done without casting at all, or a cast defined from T to int.

##### Share on other sites
Posted (edited)
8 minutes ago, Irusan, son of Arusan said:

There could also be an operator== defined for (const T&, int), so that it can be done without casting at all, or a cast defined from T to int.

Yes, that too, I was just thinking about that.You can have both, or either one, it will work, If you have both the most specific one will be called, so the (const T&, int) will take precedence if I am not mistaken.

Edit: Also if the operator== that takes an int as second parameter exists, there is no need for the int constructor, so as long as there exists or you define a free function bool operator==(const T&, int), T can be any type.

Edited by Kwizatz

##### Share on other sites

There are three ways you can look at your original example (code not tested). Each is useful depending on what you need to do:

1) T is a type and you want to see if a variable of type T has the value 2

template<typename T>
bool foo(const T& value) { return value == 2; }

....

bool isTwo = foo(2); // unless specified, 2 (eg T) is auto-cast to type 'int'

2) T is a compile-time constant and you want to see if it is 2:

template<size_t T>
bool foo() { return T == 2; }

...

bool isTwo = foo<2>();
bool isWide = foo<sizeof(wchar_t)>(); //this would be a more real worldy example, or...

...

// consider this even real worldier artifical example:

template<typename CharType>
bool IsWideString(const CharType* str) { str; return foo<sizeof(CharType>(); } // 'str;' is here to get rid of the unused parameter warning
const char* narrow;
const wchar_t* wide;
bool isWideA = IsWideString(narrow); // = false
bool isWideB = IsWideString(wide); // = true

3) T is a type, in which case the comparison makes no sense

template<typename T>
bool foo() { return std::is_integral<T>::value == 1; } // returns true if T is an integral type, signed or unsigned (this includes 'char', '__int64', etc, but not 'float' and objects)

...

bool isInteger = foo<decltype(2)>(); // decltype() gives the type that the compiler sees this value as, in this case 'int'

And here's how you fix the

## Create an account

Register a new account

• 9
• 10
• 12
• 9
• 33