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

落爺英雄遲暮 提交于 2019-12-12 07:57:19

问题


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

回答1:


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.




回答2:


You tried to initialize a pointer with an int. Many implicit conversions, including integer-to-pointer conversions, don't happen in non-type template parameters.

The cppreference summary of the behaviour in C++14 for non-template parameters of pointer to object type is:

For pointers to objects, the template arguments have to designate the address of an object with static storage duration and a linkage (either internal or external), or a constant expression that evaluates to the appropriate null pointer or std::nullptr_t value.

So the code could be:

template <void* ptr = nullptr>
void f();

Footnote: it seems unclear whether void * is allowed as a parameter type, but compilers accept the above code.



来源:https://stackoverflow.com/questions/38154762/why-using-0-as-default-non-type-template-parameter-for-void-is-not-allowed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!