【问题标题】:Having trouble with the end of this cppreference.com article这篇 cppreference.com 文章的结尾有问题
【发布时间】:2021-02-06 22:27:50
【问题描述】:

我已阅读 What does template's implicit specialization mean? 及其答案,但我仍然不满意我从 cppreference.com 了解 Partial template specialization 的这一部分:

如果主成员模板显式(完全)特化为封闭类模板的给定(隐式)特化,则对于封闭类模板的这种特化忽略成员模板的部分特化....

template<class T> struct A { //enclosing class template
  template<class T2>
  struct B {};  //primary member template
  template<class T2>
  struct B<T2*> {};  // partial specialization of member template
};
         
template<>
template<class T2>
struct A<short>::B {}; // full specialization of primary member template
                       // (will ignore the partial)
        
A<char>::B<int*> abcip; // uses partial specialization T2=int
A<short>::B<int*> absip; // uses full specialization of the primary (ignores partial)
A<char>::B<int> abci; // uses primary

问题:

  1. cmets 说template&lt;&gt; template&lt;classT2&gt; struct A&lt;short&gt;::B {}; 行是“主要成员模板的完全专业化”。主要成员模板在 cmets 中标识为结构 B。当 Ashort 替换为 class T 时,这条线怎么能成为 B 的特化?

  2. 当模板参数T2 未指定时,该行如何成为B 的“完整”特化?

  3. cmets 和随附的文本表明“显式专业化”和“完全专业化”是同义词。如果上面引用的代码行是B的显式特化,那么A的隐式特化在哪里?

【问题讨论】:

    标签: c++ templates specialization


    【解决方案1】:

    类模板的成员可以显式特化,即使它不是模板

    template<int I>
    struct X {
      int f() {return I;}
      void g() {}
    };
    template<>
    int X<0>::f() {return -1;}
    

    这相当于特化整个类模板,但其他成员复制来自相关的主模板或部分特化:

    template<>
    struct X<0> {
      int f() {return -1;}
      void g() {}
    };
    

    (回想一下,这种拼写出来的专业化根本没有义务声明 g 或声明为函数。)由于您实际上并未编写此代码,因此仍将其视为 隐式X 作为一个整体实例化,并进行给定的更改。

    这就是为什么您的A&lt;T&gt;::B 专业化为A 而不是B 提供模板参数;它用另一个模板替换模板A&lt;T&gt;::B(恰好具有相同的模板参数列表)。我想说“主要”这个词在这里具有误导性:它是被替换的 整个 模板,这就是为什么此后 A&lt;short&gt; 的部分特化被忽略的原因。

    【讨论】:

    • Davis Herring,你是说template&lt;class T2&gt; struct B&lt;T2*&gt; {} 这行是 A::B 的隐式特化吗?
    • @TRPh:“隐式专业化”并不是一个真正的东西。引号只是表示由隐式实例化生成的特化。根据定义,没有任何代码行如此隐含的,尽管一行代码可以导致隐式实例化发生。您评论中的行只是主要模板A&lt;T&gt;::B,除非部分专业化匹配或Tshort(因此使用完全独立的B 模板),否则将使用该模板。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 2015-05-01
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多