标准是否将模板类的非模板成员视为"模板"本身?

Hol*_*Cat 14 c++ language-lawyer

考虑以下代码:

#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() {}
Run Code Online (Sandbox Code Playgroud)

它来自俄罗斯StackOverflow上的这个问题,它询问它是否有效.

我试图引用这个:

[temp.res] /8.1

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

(8.1) - 不能为模板中的模板或子语句生成有效的专门化,并且模板中的constexpr if语句未实例化,或者

...

(强调我的)

由于无法生成有效的专业化foo(),因此我推断该片段格式不正确,NDR.

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

cppreference调用模板类"模板化实体"的非模板成员函数,但似乎不清楚它们本身是否可以被视为模板.

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

Sto*_*ica 10

这基本上是CWG问题1253

通用非模板成员

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

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

如果无法为模板定义生成有效的专业化,并且未实例化该模板,则模板定义格式错误,无需诊断.

这显然应该适用于类模板的非模板成员函数,而不仅仅适用于模板本身.应建立术语以引用这些通常不是模板的通用实体.

它似乎仍在起草中.但我认为,就像这个问题一样,OP中的代码也应该是格式错误的NDR.即使从不使用成员函数(因此它的完整定义永远不会被实例化),它仍然不能被假设地实例化,这将它置于错误[temp.res]/8的范畴之下.

  • @ CygnusX1 - 不,不一定.除非使用类模板,否则不会实例化类模板的非虚拟成员函数定义. (4认同)