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();
^
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.
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.
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.
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.
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.
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