依赖的非类型参数包:标准怎么说? [英] Dependent non-type parameter packs: what does the standard say?

查看:116
本文介绍了依赖的非类型参数包:标准怎么说?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为以下代码格式正确:

I think the following code is well-formed:

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)节:

Others say that it is ill-formed, because §17.7 (8.3) of the C++17 standard:

知道哪些名称是类型名称,可以检查每个模板的语法.该程序格式错误,无需进行诊断,如果:(...)可变参数模板的每个有效专业化都需要一个空的模板参数包,或(...)

我认为IsSigned< T >...是一个依赖的模板参数,因此在模板定义时无法对照§17.7(8.3)对其进行检查.对于Ts的一个子集,IsSigned< T >可以是例如void,对于另一子集或替换失败,int可以是.对于void子集,的确如此,空模板参数包将是唯一有效的专业化,但是int子集可能具有许多有效的专业化.这取决于实际的T参数.

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.

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

It means that the compiler must check it after the template instantiation, because T is not known before. At that point the full argument list is known, there is zero variadic arguments. The standard says the following (§17.6.3 (7)):

当N为零时,扩展的实例化将生成一个空列表.这样的实例化不会改变封闭结构的句法解释

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

这就是为什么我认为它的格式正确.

This is why I think it is well formed.

  • 您怎么看?
  • 我如何确定这种歧义?很难决定,因为代码可以编译,但是它什么都没有:§17.7(8.3)是NDR,编译器不必引发任何编译错误.

推荐答案

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

The code is ill-formed, no diagnostic is required.

如果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的有效专长都需要一个空的模板参数包.

If std::is_signed_v<T>, then std::enable_if_t<std::is_signed_v<T>> denotes the type void. Otherwise, std::enable_if_t<std::is_signed_v<T>> does not denote a valid type. Therefore, every valid specialization of myAbs requires an empty template parameter pack.

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

Per [meta.rqmts]/4, the program has undefined behavior if std::enable_if is specialized. Therefore, the aforementioned behavior cannot be changed.

我认为IsSigned< T >...是从属模板参数, 因此无法对照模板中的§17.7(8.3)进行检查 定义时间. IsSigned< T >例如可能是void T的子集,int表示另一个子集或替换失败.为了 void子集为真,即空模板参数包 将是唯一有效的专业化,但是int子集可以 有许多有效的专业领域.这取决于实际的T 论点.

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允许编译器不检查它.

The compiler cannot check it, in the same way it cannot, say, solve an arbitrary equation for you. NDR (no diagnostic required) is made exactly for such cases — the program is ill-formed and would require a diagnostic if the compiler is actually capable of detecting that. NDR permits the compiler not to check it.

当N为零时,展开的实例产生一个空 列表.这样的实例化不会改变语法 封闭结构的解释.

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]中.

The rule we are talking about is a semantic rule, not a syntactic rule, because syntactic rules are in [gram].

那么NDR规则的依据是什么?通常,它们解决的是实施策略中无法重现的问题.例如,它们可能会导致某些实施策略中的代码行为不当,但不会在其他实施策略中引起任何问题(也不容易).

So what is the rationale for the NDR rules? In general, they address problems that are not reproducible among implementation strategies. For example, they may cause the code to misbehave in some implementation strategies, but do not cause any problems (and cannot be easily) in others.

此外,请注意,该标准在程序方面使用诸如格式错误"之类的术语.因此,谈论隔离代码段的格式正确性并不总是合理的.在这种情况下,std::enable_if不需要专门化,但是情况可能会变得更加复杂.

Also, note that the standard talks in terms of program with terms like "ill-formed". Therefore, it is not always plausible to talk about the well-formed ness of an isolated code snippet. In this case, std::enable_if is required not to be specialized, but the situation may get more complicated otherwise.

这篇关于依赖的非类型参数包:标准怎么说?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆