C++, comparing type to integer

Started by
9 comments, last by irreversible 5 years ago

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

Advertisement

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...
  }
}

 

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.]

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".

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

https://repl.it/repls/WirelessLostLegacy

 

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
4 hours ago, ChaosEngine said:

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

https://repl.it/repls/WirelessLostLegacy

 

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

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.

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.

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.

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 

This topic is closed to new replies.

Advertisement