【问题标题】:Does the standard consider non-template members of template classes to be "templates" themselves?该标准是否认为模板类的非模板成员本身就是“模板”?
【发布时间】:2019-05-10 14:30:47
【问题描述】:

考虑以下代码:

#include <type_traits>

template <typename T> struct A
{
    static_assert(!std::is_same_v<int, T>);
};

template<typename T> struct B
{
    void foo()
    {
        A<int>{};
    }
};

int main() {}

它来自俄罗斯 StackOverflow 上的this question,它询问它是否有效。

我试图引用这个:

[temp.res]/8.1

8 可以在任何实例化之前检查模板的有效性。 [ 注意:知道哪些名称是类型名称允许以这种方式检查每个模板的语法。 — 尾注 ] 程序格式错误,不需要诊断,如果:

(8.1)无法为模板生成有效的特化或模板内的 constexpr if 语句的子语句且模板未实例化,或

...

(强调我的)

由于无法为 foo() 生成有效的特化,我推断 sn-p 格式不正确,NDR。

但有人告诉我[temp.res]/8.1 不适用,因为foo() 本身不是模板成员函数。

cppreference 将模板类的非模板成员函数称为“模板化实体”,但是否可以将其视为模板本身似乎还不清楚。

因此,问题是:标准是否认为模板类的非模板成员本身就是“模板”?

【问题讨论】:

  • [temp]/2 似乎暗示类模板的成员函数是模板,因为它的定义是 template-declaration。除了[temp]/1template-declaration 的语法图之外,该标准似乎没有正式定义术语 template
  • 这不是和什么依赖模板参数和什么不依赖有关吗? A&lt;int&gt; 总是相同的东西,不管B 被实例化时给出的模板参数T 是什么。编译器将能够识别出上述构造将失败。另一方面,如果你有A&lt;T&gt;{},那么它依赖于模板参数TB)。在实例化发生之前,编译器不会努力识别T 的哪些值会失败,哪些不会。可能是 所有 个可能的 T 值导致错误。
  • [temp.mem.func]/1 中的一个(不可否认的非规范性)示例显示了一个具有三个成员函数的类模板,并说代码“声明了三个函数模板”。所以至少作者的意图似乎是将成员函数视为模板。
  • 反对“类模板的成员就是模板”:[temp]/9[temp.names]/2[temp.dep.expr]/3.6[temp.expl.spec]/6

标签: c++ language-lawyer


【解决方案1】:

这本质上是CWG issue 1253

通用非模板成员

部分:17.8 [temp.spec] 状态:起草提交者:Nikolay Ivchenkov 日期:2011- 03-06

标准中的许多声明仅适用于模板,例如, 17.7 [temp.res] 第 8 段:

如果无法为模板定义生成有效的特化, 并且该模板未实例化,模板定义为 格式不正确,无需诊断。

这显然应该适用于类的非模板成员函数 模板,而不仅仅是模板本身。术语应该是 建立来指代这些实际上并不存在的通用实体 模板。

它似乎仍在起草中。但我认为,就像这个问题一样,OP 中的代码应该也是格式不正确的 NDR。即使成员函数从未被使用(因此其完整定义从未被实例化),它仍然无法被假设实例化,这将其置于 [temp.res]/8 旨在涵盖的错误类别中。

【讨论】:

  • 不属于 OP 示例(“由于不依赖于模板参数的构造,紧随其定义的模板的假设实例化将是错误的)[eel.is/c++draft/temp.res#8.4] ?
  • @CygnusX1 - 问题的症结在于该成员是否属于模板的定义,是否适用本段。这对我来说似乎不是结论性的,我认为 CWG 问题仍然活跃,支持这一断言。
  • 我不确定该成员本身是否是一个模板。但是,B 整体一个模板,尝试实例化B 会导致错误。
  • @CygnusX1 - 不,不一定。类模板的非虚拟成员函数定义除非被使用,否则不会被实例化。
  • 你完全正确,我的立场是正确的。我学到了一些新东西:)
猜你喜欢
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 2013-12-20
  • 1970-01-01
  • 1970-01-01
  • 2018-11-28
  • 1970-01-01
  • 2019-04-12
相关资源
最近更新 更多