首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么不允许使用0作为void*的默认非类型模板参数

为什么不允许使用0作为void*的默认非类型模板参数
EN

Stack Overflow用户
提问于 2016-07-01 22:49:28
回答 2查看 1.1K关注 0票数 9

为什么以下代码无法编译?即使做void* ptr = 0;是合法的

代码语言:javascript
复制
template <void* ptr = 0>
void func();

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

我之所以问这个问题,是因为我发现一个非常可信的源代码做了类似的事情,但它未能在我的机器上编译。

注意:应该将编译器错误连同我的问题一起发布,所以这里是

代码语言:javascript
复制
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();
     ^
EN

回答 2

Stack Overflow用户

发布于 2016-07-01 22:53:43

不允许使用void*类型的模板参数。参见标准中的tem.param/4,也在参数中作了总结

非类型模板参数应具有下列类型之一(可选cv限定类型):

  • 整型或枚举型,
  • 指向对象或指向函数的指针,
  • lvalue引用对象或lvalue引用函数,
  • 指向成员的指针,
  • std::nullptr_t

由于void不是对象或函数类型,所以void*不属于允许的类型。

增编:编译时已知的void*值将不是很有用。不可能在编译时检查它的值,因为常量表达式中不允许reinterpret_cast;也不可能在编译时将某些对象类型的T转换为T*

票数 9
EN

Stack Overflow用户

发布于 2016-07-01 23:49:25

您尝试使用int初始化指针。许多隐式转换,包括整数到指针转换,不发生在非类型模板参数中。

指向对象类型的指针的非模板参数在C++14中的行为的偏好摘要是:

对于指向对象的指针,模板参数必须指定具有静态存储持续时间和链接(内部或外部)的对象的地址,或计算为适当的空指针或std::nullptr_t值的常量表达式。

因此,代码可以是:

代码语言:javascript
复制
template <void* ptr = nullptr>
void f();

脚注:似乎不清楚是否允许void *作为参数类型,但编译器接受上述代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38154762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档