Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why using 0 as default non type template parameter for void* is not allowed

Why does the following code fail to compile? Even though it is legal to do void* ptr = 0;

template <void* ptr = 0>
void func();

int main() {
    func();
    return 0;
}

I ask because I found that a very trusted source did something similar and it failed to compile on my machine

NOTE Should have posted the compiler error along with my question so here it is

so_test.cpp:1:23: error: null non-type template argument must be cast to template parameter type 'void *'
template <void* ptr = 0>
                      ^
                      static_cast<void *>( )
so_test.cpp:1:17: note: template parameter is declared here
template <void* ptr = 0>
                ^
so_test.cpp:5:5: error: no matching function for call to 'func'
    func();
    ^~~~
so_test.cpp:2:6: note: candidate template ignored: substitution failure [with ptr = nullptr]: null non-type template argument must be cast to template parameter type 'void *'
void func();
     ^
like image 301
Curious Avatar asked Jul 01 '16 22:07

Curious


People also ask

Which parameter is allowed for non-type template?

Which parameter is legal for non-type template? Explanation: The following are legal for non-type template parameters:integral or enumeration type, Pointer to object or pointer to function, Reference to object or reference to function, Pointer to member.

Can we use non-type parameters as arguments template?

Non-type template arguments are normally used to initialize a class or to specify the sizes of class members. For non-type integral arguments, the instance argument matches the corresponding template parameter as long as the instance argument has a value and sign appropriate to the parameter type.

Can template parameters have default values?

Just like in case of the function arguments, template parameters can have their default values. All template parameters with a default value have to be declared at the end of the template parameter list.

Which is correct example of template parameters?

For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.


1 Answers

Template parameters of type void* are not allowed. See [temp.param]/4 in the standard, also summarized at http://en.cppreference.com/w/cpp/language/template_parameters#Non-type_template_parameter

A non-type template-parameter shall have one of the following (optionally cv-qualified) types:

  • integral or enumeration type,
  • pointer to object or pointer to function,
  • lvalue reference to object or lvalue reference to function,
  • pointer to member,
  • std::nullptr_t.

Since void is not an object or function type, void* is not among the permitted types.

Addendum: A void* value known at compile time wouldn't be very useful. It's not possible to examine its value at compile time since reinterpret_cast is not allowed in constant expressions; nor is it possible to convert it to T* for some object type T at compile time.

like image 145
Brian Bi Avatar answered Sep 28 '22 03:09

Brian Bi