Nullptr as a template parameter

I have a template like:

template <class A, class B>
void func(A* a, B* b){
  ...
}

      

In some cases, it happens that the parameter is B* b

not needed, and therefore I try to use nullptr:

MyA a;
func(&a, nullptr);

      

The compiler doesn't like this as it is nullptr

somehow not a type.

How can I handle this situation? The only idea is to just use a dummy type for this case.

+3


source to share


3 answers


The problem is that it nullptr

is not actually a pointer, but an object of the type nullptr_t

. Thus, it cannot match either A*

or B*

. One option is to provide an overload to specifically handle nullptr_t

.

template<class A>
void func(A* a, nullptr_t)
{
    func(a, (int*)nullptr);
}

      

If you also want to resolve the first argument nullptr

, you can provide two more overloads. One to handle only the first argument, and one to handle both.



template<class B>
void func(nullptr_t, B* b)
{
    func((int*)nullptr, b);
}

void func(nullptr_t, nullptr_t)
{
    func((int*)nullptr, (int*)nullptr);
}

      

For any additional arguments, this approach becomes infeasible without code generation, since the number of required overloads is an exponential function of the number of arguments. In this case, I would recommend the jrok approach.

+7


source


Besides the overloading suggested by Benjamin Lindley , another option conditionally allows a function if the types A

and B

are pointers, or std::nullptr_t

:

#include <type_traits>

template<typename T>
struct is_pointer : std::integral_constant<bool,
                        std::is_pointer<T>::value ||
                        std::is_same<T, std::nullptr_t>::value    
                    >
{};

template <class A, class B>
typename std::enable_if<
   is_pointer<A>::value && is_pointer<B>::value
>::type
func(A a, B b) { }

      



But sometimes the simplest is the best, so maybe the second overload template<class A> func(A*);

will do the job.

+2


source


when you want to call this function, you can do the following instead of other ways:

    func<a, b>(var_a, nullptr);

      

by doing this you are just passing your template to work and you can have your own type

0


source







All Articles