Olumide
Olumide

Reputation: 5809

Cannot convert template argument NULL to void*

I've distilled a problem that's confounded me to the minimal example shown below. Basically the gcc compiler doesn't accept NULL as a template parameter of type void*.

Is there a workaround for this?

Please note that I'm restricted to C++03.

#define NULL 0

template<typename T = void , T* = NULL>
struct Foo
{
};

typedef Foo<> FooType;

int main()
{
}

Edit: online version

Upvotes: 1

Views: 450

Answers (1)

zneak
zneak

Reputation: 138031

There is no solution to your problem: C++03 pointer template parameters have to designate an object. Using NULL as a non-type template parameter is a feature that was added in N1905, which came out at least one year after C++03.

14.3.2 Template non-type arguments

A template-argument for a non-type, non-template template-parameter shall be one of:

  • an integral constant-expression of integral or enumeration type; or
  • the name of a non-type template-parameter; or
  • the address of an object or function with external linkage, including function templates and function template-ids but excluding non-static class members, expressed as & id-expression where the & is optional if the name refers to a function or array, or if the corresponding template-parameter is a reference; or
  • (NEW) a constant expression that evaluates to a null pointer value (4.10); or
  • (NEW) a constant expression that evaluates to a null member pointer value (4.11); or
  • a pointer to member expressed as described in 5.3.1.

One option is to declare a "null struct" with a member that you can use instead of a real NULL:

template<typename T>
struct null
{
    static T value;
};

template<typename T, T* = &null<T>::value>
struct Foo
{
};

Of course, accessing null<T>::value has well-defined semantics and it won't crash; the purpose is just to have an address that is guaranteed to be different from the address of any other object.

Note that in any case, it will be impossible for you to use T = void. You can't use the null workaround with it because void is an incomplete type; and you can't cast anything to a void pointer to use as a non-type template argument.

Upvotes: 3

Related Questions