L. *_* F. 11 c++ templates language-lawyer c++17 c++20
void*在标准的至少某些版本中,不允许使用type的非类型模板参数。
这是真的?如果为真,则在哪些版本的标准中void*不允许使用非类型模板参数?
(注意:正如在
回答
另一个评论的评论中所指出的
,这是关于非类型模板参数,而不是模板类型参数,模板参数可以是每个
[temp.arg.type]的有效type-id,包括。void*
L. *_* F. 14
类型的模板参数void*自C ++ 20起有效。它们在C ++ 20之前无效。
C ++ 20放宽了对非类型模板参数类型的限制,因此让我们首先对其进行研究。
当前草案(截至UTC 2019年5月6日10:00)以[temp.param] / 4表示:
非类型模板参数应具有以下(可选,具有cv限定)类型之一:
- 具有强等式结构的文字类型([class.compare.default]),
- 左值引用类型,
- 包含占位符类型([dcl.spec.auto])的类型,或
- 推导类类型([dcl.type.class.deduct])的占位符。
void*是指针类型。指针类型是标量类型([basic.types] / 9)。甲标量类型是文本类型([basic.types] / 10)。因此,void*是一个文字类型。第一个项目符号是相关的。
进一步追踪,[class.compare.default] / 3表示:
如果给定type 的glvalue ,则类型
C具有强结构相等性:xconst C
C是非类类型,并且x <=> x是类型std::strong_ordering或的有效表达式std::strong_equality,或者
C是的类型类型,其==运算符在的定义中定义为默认值C,x == x在上下文转换为时格式正确bool,所有C的基类子对象和非静态数据成员都具有很强的结构相等性,并且C没有mutable或volatile子对象。
void*是非类类型,因此第一个项目符号是相关的。现在,问题归结为x <=> x
where x是type的glvalue的类型void* const(不是const void*)。每[expr.spaceship] / 8:
如果复合指针类型是对象指针类型,
p <=> q则类型为std::strong_ordering。如果两个指针操作数p并且q比较等于([expr.eq]),则p <=> q得出std::strong_ordering::equal; 如果p和q比较不相等,则p <=> q产生“std::strong_ordering::less如果q比较大于”p和“std::strong_ordering::greater如果p比较大于”q([expr.rel])。否则,结果不确定。
请注意,这void*是一个对象指针类型([basic.compound] / 3)。因此,x <=> x是类型std::strong_ordering。因此,该类型void*具有很强的结构相等性。
因此,在当前的C ++ 20草案中,
void*允许将其作为模板参数类型的类型。
现在我们解决C ++ 17。 [temp.param]说:
非类型模板参数应具有以下(可选,具有cv限定)类型之一:
- 整数或枚举类型,
- 指向对象或函数的指针,
- 对对象的左值引用或对函数的左值引用,
- 指向成员的指针,
std?::?nullptr_t, 要么- 包含占位符类型的类型。
注意,“指针对象”不包括void*
每[basic.compound] / 3:
[?注意:指向的指针
void没有指向对象的指针类型,因为void它不是对象类型。-?尾注?]
以上六个项目符号均未包含void*
模板参数的可能类型。因此,在C ++ 17中,模板参数不得具有type void*。
C ++ 11和C ++ 14的措辞相同,只是不存在有关占位符类型的符号。通常,
在C ++ 20之前,模板参数不得具有type void*。
TC在 评论中 说,没有人诊断出该IHRC。让我们用下面显示的最小示例来测试编译器是否以C ++ 17模式进行诊断:
template <void*>
class C {};
int main()
{
C<nullptr> x;
(void) x;
}
Run Code Online (Sandbox Code Playgroud)
该代码可以在GCC 9.1.0, GCC 8.3.0, GCC 7.3.0, GCC 6.3.0, GCC 5.5.0, Clang 8.0.0, Clang 7.0.0, Clang 6.0.1和Clang 5.0上编译并正常运行 .0。
NathanOliver在评论中告诉我,有人告诉他某些编译器会出错,但是主要的编译器不会出错。因此,据我所能确认的,TC的说法是正确的-没有人能诊断出这一点。
| 归档时间: |
|
| 查看次数: |
280 次 |
| 最近记录: |