10

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.

3
  • 4
    nullptr is of type nullptr_t. Commented Jun 7, 2015 at 18:41
  • 2
    What is the error message? Commented Jun 7, 2015 at 18:42
  • 1
    nullptr is not a pointer, its type is nullptr_t, which cannot be matched with B*, but you can manually do so by func(&c, (int*)nullptr);, it's not optimal for user though. Commented May 1, 2022 at 15:11

4 Answers 4

15

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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.

1 Comment

nullptr will not work if we need to use some pointer related actions on b(e.g. *b, b->foo), in this case we may need another type cast on b.
0

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

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

by doing this, you just pass your template to function and you can have your own type

Comments

0

This is just another hacky way of doing it, but it works:

T* tNullptr = nullptr;
functionWithTemplate(otherArgument1, tNullptr)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.