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

时间:2018-12-09 13:47:35

标签: 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() {}

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

我尝试引用此内容:

  

[temp.res]/8.1

     

8 可以在任何实例化之前检查模板的有效性。 [注意:知道哪些名称是类型名称,这样就可以检查每个模板的语法。 —注释] 该程序格式不正确,无需进行诊断,如果:

     

(8.1)如果模板中的语句未被实例化,则无法为模板或constexpr的子语句生成有效的专业化版本,或者< / p>      

...

(重点是我的)

由于无法为foo()生成有效的专业化,因此我认为该代码段的格式错误,即NDR。

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

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

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

1 个答案:

答案 0 :(得分:9)

这实际上是CWG issue 1253

  

通用非模板成员

     

部分:17.8 [temp.spec] 状态:起草 Submitter :Nikolay Ivchenkov Date :2011- 03-06

     

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

     
    

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

  
     

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

它似乎仍在起草中。但我认为,像问题一样,OP 中的代码也应采用格式错误的NDR。即使从不使用成员函数(因此也永远不会实例化其完整定义),它甚至也无法假设地实例化,这使其属于错误[temp.res] / 8的范畴。