
said:
Non-type template parameters of type
void*are not allowed in at
least some versions of the standard.
这是真的?
如果是,那么标准的哪个版本是不允许的类型为void *的非类型模板参数?
(注:如中所述)
a comment
回答
another comment,
这是关于非类型模板参数,
不是模板类型参数,
可以是任何有效的type-id per
[temp.arg.type],
包括void *.
类型为void *的模板参数自C 20起有效.
它们在C 20之前无效.
C 20
C 20放宽了对非类型模板参数类型的限制,
所以我们先来调查吧.
目前的草案(截至2019年5月6日UTC 10:00)在[temp.param]/4中说:
A non-type template-parameter shall have one of the following
a literal type that has strong structural equality ([class.compare.default]), an lvalue reference type, a type that contains a placeholder type ([dcl.spec.auto]), or a placeholder for a deduced class type ([dcl.type.class.deduct]).
(optionally cv-qualified) types:
void *是指针类型.
指针类型是标量类型([basic.types]/9).
标量类型是文字类型([basic.types]/10).
因此,void *是文字类型.
第一颗子弹是相关的.
进一步追踪,[class.compare.default]/3说:
A type
Chas strong structural equality if, given a glvaluexof
typeconst C, either:
Cis a non-class type andx <=> xis a valid expression of typestd::strong_orderingorstd::strong_equality, or
Cis a class type with an==operator defined as defaulted in the definition ofC,x == xis well-formed when contextually
converted tobool, all ofC‘s base class subobjects and non-static
data members have strong structural equality, andChas nomutable
orvolatilesubobjects.
void *是非类型的,
所以第一颗子弹是相关的.
现在问题归结为x< =>的类型. X
其中x是void * const类型的glvalue(不是const void *).
每[expr.spaceship]/8:
If the composite pointer type is an object pointer type,
p <=> qis
of typestd::strong_ordering. If two pointer operandspandq
compare equal ([expr.eq]),p <=> qyields
std::strong_ordering::equal; ifpandqcompare unequal,p <=>yields
qstd::strong_ordering::lessifqcompares greater than
pandstd::strong_ordering::greaterifpcompares greater than
q([expr.rel]). Otherwise, the result is unspecified.
请注意,void *是对象指针类型([basic.compound]/3).
因此,x< => x的类型为std :: strong_ordering.
因此,类型void *具有强烈的结构相等性.
因此,在目前的C 20草案中,
允许void *作为模板参数类型的类型.
C 17
现在我们解决C 17.
[temp.param]说:
A non-type template-parameter shall have one of the following
integral or enumeration type, pointer to object or pointer to function, lvalue reference to object or lvalue reference to function, pointer to member,
(optionally cv-qualified) types:std::nullptr_t, or a type that contains a placeholder type.
请注意,“指向对象的指针”不包含void *
每[basic.compound]/3:
[ Note: A pointer to
voiddoes not have a pointer-to-object type, however, becausevoidis not an object type. — end note ]
上述六发子弹中没有一个包含空*
作为模板参数的可能类型.
因此,在C 17中,
模板参数的类型不能为void *.
对于C 11和C 14,措辞是相同的
除了关于占位符类型的子弹不在那里.
一般来说,
在C 20之前,
模板参数的类型不能为void *.
但是编译器会诊断出来吗?
T.C.在一篇文章中说
comment
没有人诊断出这个IHRC.
让我们测试编译器是否在C 17模式下诊断出来
使用如下所示的最小示例:
template <void*>
class C {};
int main()
{
C<nullptr> x;
(void) x;
}
代码编译并运行良好
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在comment告诉我,有人告诉他一些编译器会出错,但主要的不会.因此,据我所知,T.C.的陈述是正确的 – 没有人诊断出这一点.
转载注明原文:c – 非类型模板参数可以是“void *”类型吗? - 乐贴网