用户定义的推导指南是否涉及模板模板参数作为指南标准的模板
Are user defined deduction guides involving template template parameter as a template for guidance standard compliant
背景
昨天我问了一个关于. I was really surprised when Barry changed his answer to the confirmation of standard complianceness of the code. My surprise doesn't actually come from the fact deduction guides can be applied for template template parameters, but more from the standard part which conforms this compliance, namely [temp.param]/3的问题:
A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared without template
) or template-name (if declared with template
) in the scope of the template declaration.
加上 [temp.deduct.guide]/1 and the rule for simple-template-id 可以创建一个接受任何模板的通用演绎指南。
例子
#include <string>
template <class T>
struct Foo {
Foo(T) { }
};
template <template <class> class TT>
TT(const char *) -> TT<std::string>;
int main() {
Foo foo("abc");
}
问题
代码导致 gcc to crash with internal error and results in compilation error in clang。坦率地说,我 不是 说代码实际上应该在 C++ 中允许,但认为当前的措辞确实使它符合要求。我是否遗漏了一些禁止代码的重要规则?
你的例子
冒着犯错的风险,我会引用一个现已删除的答案
If I'm not mistaken this goes afoul of [temp.deduct.guide]p3:
The simple-template-id shall name a class template specialization.
TT<std::string>
没有命名 class 模板专业化,您的代码格式不正确。
[temp.spec]p4中也有这个:
A specialization is a class, function, or class member that is either instantiated or explicitly specialized.
TT
在技术上是一个模板 type-parameter。构造 TT<std::string>
是类型依赖的 type-name。如果推导指南是一个实际的函数模板并且我们将其实例化,TT<std::string>
可以实例化为 class-name 引用 class 模板专业化。如果实例化 TT
以引用适当定义的别名模板,它也可以引用 int
。但按原样,在演绎指南声明中,它还没有命名 class 模板专业化。
[temp.res]p8.5.5 中有一条规则说
Otherwise, no diagnostic shall be issued for a template for which a valid specialization can be generated.
那么,演绎指南的专业化完全可以吗?我反对 no。首先,它不是可以实例化的 "templated entity" (c.f. [temp]p8)。 class 模板参数推导的专长是一组模板根据推导指南形成,而不是指南本身。参见 [over.match.class.deduct]p1.4
[...] For each deduction-guide, a function or function template with the following properties [is formed]: [...]
正是那些在重载解析过程中进一步专门化的函数模板。推导指南本身从不专门化,因此,我们可以生成一条诊断消息,用于违反推导指南中的 simple-template-id 未命名 [=68] 的规则=] 模板专业化。
通过别名模板命名(Richard 的示例)
理查德举了一个不同的例子
template<typename T> class X { T t; };
template<typename T> using Y = X<T*>;
template<typename T> Y(T) -> Y<T>;
在这种情况下,它更复杂,我认为这可能是措辞允许的,因为 Y<T>
实际上是 class 模板特化。在应用重写规则后,您现在可以争论它实际上是 命名 专业化还是仅 表示 它。它允许争论的事实似乎足以保证缺陷报告,IMO。
背景
昨天我问了一个关于
A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared without
template
) or template-name (if declared withtemplate
) in the scope of the template declaration.
加上 [temp.deduct.guide]/1 and the rule for simple-template-id 可以创建一个接受任何模板的通用演绎指南。
例子
#include <string>
template <class T>
struct Foo {
Foo(T) { }
};
template <template <class> class TT>
TT(const char *) -> TT<std::string>;
int main() {
Foo foo("abc");
}
问题
代码导致 gcc to crash with internal error and results in compilation error in clang。坦率地说,我 不是 说代码实际上应该在 C++ 中允许,但认为当前的措辞确实使它符合要求。我是否遗漏了一些禁止代码的重要规则?
你的例子
冒着犯错的风险,我会引用一个现已删除的答案
If I'm not mistaken this goes afoul of [temp.deduct.guide]p3:
The simple-template-id shall name a class template specialization.
TT<std::string>
没有命名 class 模板专业化,您的代码格式不正确。[temp.spec]p4中也有这个:
A specialization is a class, function, or class member that is either instantiated or explicitly specialized.
TT
在技术上是一个模板 type-parameter。构造 TT<std::string>
是类型依赖的 type-name。如果推导指南是一个实际的函数模板并且我们将其实例化,TT<std::string>
可以实例化为 class-name 引用 class 模板专业化。如果实例化 TT
以引用适当定义的别名模板,它也可以引用 int
。但按原样,在演绎指南声明中,它还没有命名 class 模板专业化。
[temp.res]p8.5.5 中有一条规则说
Otherwise, no diagnostic shall be issued for a template for which a valid specialization can be generated.
那么,演绎指南的专业化完全可以吗?我反对 no。首先,它不是可以实例化的 "templated entity" (c.f. [temp]p8)。 class 模板参数推导的专长是一组模板根据推导指南形成,而不是指南本身。参见 [over.match.class.deduct]p1.4
[...] For each deduction-guide, a function or function template with the following properties [is formed]: [...]
正是那些在重载解析过程中进一步专门化的函数模板。推导指南本身从不专门化,因此,我们可以生成一条诊断消息,用于违反推导指南中的 simple-template-id 未命名 [=68] 的规则=] 模板专业化。
通过别名模板命名(Richard 的示例)
理查德举了一个不同的例子
template<typename T> class X { T t; };
template<typename T> using Y = X<T*>;
template<typename T> Y(T) -> Y<T>;
在这种情况下,它更复杂,我认为这可能是措辞允许的,因为 Y<T>
实际上是 class 模板特化。在应用重写规则后,您现在可以争论它实际上是 命名 专业化还是仅 表示 它。它允许争论的事实似乎足以保证缺陷报告,IMO。