gpt4 book ai didi

c++ - 依赖非类型参数包 : what does the standard say?

转载 作者:可可西里 更新时间:2023-11-01 18:30:09 27 4
gpt4 key购买 nike

我认为下面的代码格式正确:

template< typename T >
using IsSigned = std::enable_if_t< std::is_signed_v< T > >;

template< typename T, IsSigned< T >... >
T myAbs( T val );

也有人说它是病式的,因为C++17标准的§17.7 (8.3):

Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if: (...) every valid specialization of a variadic template requires an empty template parameter pack, or (...)

在我看来IsSigned< T >...是一个依赖模板参数,因此在模板定义时不能根据 §17.7 (8.3) 检查它。 IsSigned< T >例如可以是 void对于 Ts 的一个子集,int对于另一个子集或替换失败。对于 void subset 确实如此,空模板参数包将是唯一有效的特化,但是 int subset 可以有很多有效的特化。这取决于实际 T争论。

这意味着编译器必须在模板实例化之后检查它,因为T之前是未知的。那时完整的参数列表是已知的,可变参数为零。该标准规定如下(§17.6.3 (7)):

When N is zero, the instantiation of the expansion produces an empty list. Such an instantiation does not alter the syntactic interpretation of the enclosing construct

这就是为什么我认为它的格式很好。

  • 你怎么看?
  • 我怎样才能确定地找出这种歧义?很难决定,因为代码编译但没有任何意义:§17.7 (8.3) 是 NDR,编译器不必引发任何编译错误。

最佳答案

代码格式错误,不需要诊断。

如果std::is_signed_v<T> , 然后 std::enable_if_t<std::is_signed_v<T>>表示类型 void .否则,std::enable_if_t<std::is_signed_v<T>>不表示有效类型。因此,myAbs 的每个有效特化需要一个空的模板参数包。

根据 [meta.rqmts]/4 ,如果std::enable_if,程序有未定义的行为是专门的。因此,上述行为无法改变。

In my opinion IsSigned< T >... is a dependent template parameter, therefore it can not be checked against §17.7 (8.3) in template definition time. IsSigned< T > could be for example void for one subset of Ts, int for another subset or substitution failure. For the void subset it is true, that the empty template parameter pack would be the only valid specialization, but the int subset could have many valid specializations. It depends on the actual T argument.

编译器无法检查它,就像它无法为您求解任意方程一样。 NDR(不需要诊断)正是为这种情况而设计的——程序格式错误,如果编译器确实能够检测到,则需要进行诊断。 NDR 允许编译器不检查它。

When N is zero, the instantiation of the expansion produces an empty list. Such an instantiation does not alter the syntactic interpretation of the enclosing construct.

我们说的规则是语义规则,不是句法规则,因为句法规则是以[gram]为单位的。


那么 NDR 规则的基本原理是什么?一般来说,它们解决的问题在实现策略中是不可重现的。例如,它们可能会导致代码在某些实现策略中行为不当,但不会在其他实现策略中引起任何问题(而且不容易)。


另外,请注意标准在程序方面使用诸如“格式错误”之类的术语。因此,谈论一个孤立代码片段的格式是否正确并不总是合理的。在这种情况下,std::enable_if要求不专业,否则情况可能会变得更复杂。

关于c++ - 依赖非类型参数包 : what does the standard say?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57783393/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com