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.
source to share
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.
source to share
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.
source to share