0

Let's say that I have this generic function:

template<typename T>
void foo(T data) {
  if(data == nullptr)
   return;
  //...
}

The problem is that I can not really write something like that. If T is a primitive type or an object passed by value, I can not compare it with the nullptr.

On the other hand, what if T is a pointer to an int? I would like to be able to compare it with the nullptr.

Is there any way?

Kami
  • 1,079
  • 2
  • 13
  • 28
  • 2
    Change the template to `foo(T * data)`. – Kerrek SB Jun 26 '14 at 08:59
  • I thought about that, but I want both normal values and pointers as T. Maybe what I am asking can not be done(like in Java). The problem is that my compiler accepts a call to foo(nullptr) without complaining if I set T to something like int*. Should it stop me from doing that? – Kami Jun 26 '14 at 09:02
  • 1
    Do you want `if (data == T{})` ? – Jarod42 Jun 26 '14 at 09:03
  • Sorry I do not know the meaning of that expression. I want both class types and pointer types to be boundable to T. The problem is that I can not compare a class type(a value) to nullptr. – Kami Jun 26 '14 at 09:11
  • 2
    @Kami: It's unclear what you want to do. (I'm particularly puzzled by why you think the compiler should stop you from calling `foo(nullptr);` -- why do you think it should stop you?) If you want 2 versions of `foo()`, one that will take pointer types and test them against `nullptr` and one that will take non-pointer types (and not test them againts `nullptr`), then you can make 2 overloaded function templates. – j_random_hacker Jun 26 '14 at 09:12
  • Why foo is possible with a type T? It should be only possible if I wrote T* explicitly(void foo(T *data)...). That was my point. – Kami Jun 26 '14 at 09:16
  • What does this function do? (It can handle both integers and pointers?) Why must it reject null pointers? – dyp Jun 26 '14 at 09:28
  • I see that there is `std::is_pointer`. You could use that to branch into different code paths depending on the result. But I also like what @Jarod42 suggested. T{} zero-initializes pointers, i.e. results in nullptr, and/or default-initializes other types, depending on what ctors are available. – Peter - Reinstate Monica Jun 26 '14 at 09:29
  • @Kami: Based on your last comment, it seems you think that `int*` is not a type -- but it's a type (called "pointer to `int`") in the same category as `int` itself. A type parameter, like `T` in `template ...`, can be replaced with *any* type, including `int*` (or weirder types like `float (int&, char*(*)[42])`, which is the type of a function that takes a reference to `int` and a pointer to an array of 42 pointers to `char`, and returns a `float`), though this may generate downstream errors in the instantiated code. – j_random_hacker Jun 27 '14 at 04:13

1 Answers1

4

As @j_random_hacker suggested, just overload the foo() function. This way you have 2 differents behaviour depending of the type you pass to foo()

template<typename T>
void foo(T *data)
{
  if(data == nullptr)
    return;
  //...
}

template<typename T>
void foo(T data)
{
  //...
}