I have a template like:
template <class A, class B>
void func(A* a, B* b){
...
}
In some cases it happens that parameter B* b
is not needed and therefore, I try to use a nullptr:
MyA a;
func(&a, nullptr);
The compiler doesn't like that since nullptr
somehow is not a type.
How can I deal with that situation? The only idea is to just use a dummy type for that case.
The problem is that nullptr
is not actually a pointer, but an object of type nullptr_t
. So it cannot match either A*
or B*
. One option would be 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 allow the first argument to be nullptr
, you can provide 2 more overloads. One to handle just 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 more arguments, this approach becomes unfeasible without code generation, as the number of overloads required is an exponential function of the number of arguments. In that case, I would recommend jrok's approach.
Besides the overloading as suggested by Benjamin Lindley, another option is conditionaly enabling the function if the types A
and B
are either a pointer 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 a second overload template<class A> func(A*);
will do the job.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With