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.
nullptris of typenullptr_t.nullptris not a pointer, its type isnullptr_t, which cannot be matched withB*, but you can manually do so byfunc(&c, (int*)nullptr);, it's not optimal for user though.