空指针作为 C++ 中的模板参数 [英] Void pointer as template argument in C++
问题描述
以下内容无法编译:
template<void *p>
class X {
// ...
};
int r;
int main()
{
X<&r> x;
return 0;
}
错误信息是
x.cc:10:6: 错误:无法转换模板参数‘&r' 到 'void*'
x.cc:10:6: error: could not convert template argument ‘& r’ to ‘void*’
将 &r 显式转换为 (void *) 也无济于事.错误信息变为:
Explicitly casting &r to (void *) doesn't help either. The error message becomes:
x.cc:10:14: 错误:无法将模板参数‘(void*)(& r)’转换为‘void*’
x.cc:10:14: error: could not convert template argument ‘(void*)(& r)’ to ‘void*’
标准的哪一部分规定了这种行为?GCC 版本为 gcc version 5.2.1 20151003 (Ubuntu 5.2.1-21ubuntu2)
Which part of the standard specifies that behaviour? The GCC version is gcc version 5.2.1 20151003 (Ubuntu 5.2.1-21ubuntu2)
请注意,使用例如int * 而不是 void * 按预期工作.
Please note that using e.g. int * instead of void * works as expected.
(回答我自己)
当指定 -std=c++1z 时,它不与 gcc HEAD 6.0.0 20151016(实验性)一起工作,既不隐式也不显式转换为空*".
It does not work with gcc HEAD 6.0.0 20151016 (experimental) when specifying -std=c++1z, neither with implicit nor with explicit casting to "void *".
它确实与 clang HEAD 3.8.0 (trunk 250513) 一起使用,并且从(至少)clang 3.6.0 (tags/RELEASE_360/final) 指定 --std=c++1z 并显式转换为 *void *" 时.如果没有明确的演员表,clang 会抱怨如下:
It does work with clang HEAD 3.8.0 (trunk 250513) and has been since (at least) clang 3.6.0 (tags/RELEASE_360/final) when specifying --std=c++1z and explicitly casting to *void *". Without the explicit cast, clang complains as follows:
x.cc:10:7: 错误:在转换后的常量表达式中不允许从int *"到void *"的转换
x.cc:10:7: error: conversion from 'int *' to 'void *' is not allowed in a converted constant expression
负责在 c++ 语言规范中修复此错误的是 N4268 已经实现了.
Responsible for fixing this bug in the c++ language specification is N4268 which clang already implements.
推荐答案
我不能引用你头顶的章节和诗句(欢迎编辑),但你试图做的事情不允许在C++.
I can't quote you the chapter and verse off the top of my head (edits are welcome), but what you are trying to do is not allowed in c++.
模板参数在编译时必须是已知的.指针仅在链接时解析,除非:
Template parameters must be known at compile time. Pointers are only resolved at link time unless:
它们在模板参数列表中默认使用
= nullptr
.
它们是成员函数指针(在编译时是已知的,因为它们只是偏移量).
they are member function pointers (which are known at compile time since they are merely offsets).
例如,这将编译:
template<void * = nullptr>
class X {
// ...
};
int r;
int main()
{
X<nullptr> x;
return 0;
}
这篇关于空指针作为 C++ 中的模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!