Jump to content
  • Advertisement
too_many_stars

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!