首页 > 解决方案 > c++显式特化不能访问primay模板成员但可以访问部分特化成员?

问题描述

#include <iostream>
using namespace std;

template<class T, int I>  // primary template
struct A {
    void f(); // member declaration
};
 
template<class T, int I>
void A<T,I>::f() { } // primary template member definition
 
// partial specialization
template<class T>
struct A<T,2> {
    void f();
    void g();
    void h();
};
 
// member of partial specialization
template<class T>
void A<T,2>::g() { 
    cout << "partial g()" << endl;
}

template<class T>
void A<T,2>::h() { 
    cout << "partial h()" << endl;
}
 
// explicit (full) specialization
// of a member of partial specialization
template<>
void A<char,2>::h() {
    cout << "explicit h()" << endl;
}
 
int main() {
    A<char,2> a2;
    a2.f(); // ERROR, partial can not access primary member
    a2.g(); // OK, uses partial specialization's member definition
    a2.h();  // OK, explicit h() being called.
}

我通过了cpp 参考,它说

“部分专业的成员与主模板的成员无关。”

所以可以理解,a2 不能访问主要专业的成员a2.f()

我的问题是

  1. 部分特化成员和显式特化成员之间的关系如何?

  2. 为什么 a2 可以在这里访问偏特化的成员a2.g()

标签: c++templates

解决方案


重要的是要认识到类模板不是一个类,而只是一个类的蓝图。

A<char,2>匹配专门的蓝图,所以它有f,g,h成员函数。主模板的内容被完全忽略。

因为A是一个模板类,它的方法只有在实际调用时才会被实例化,并且只针对那些具体的模板参数,因为实例化A是一个类,因此它只有一组方法。

  • 由于您没有定义 any A<char,2>::f,因此链接器会报告undefined reference错误。
  • A<char,2>::g实例化函数有一个可用的定义template<class T> void A<T,2>::g() ——即普通方法,而不是函数模板。
  • 出于同样的原因,A<char,2>::h也可以编译 - 这个函数有一个定义,不需要更多。

简而言之,编译器只会查找它需要的定义,如果找到匹配的模板,它将生成定义。否则,它将将该符号标记为丢失,并且您有责任让链接器使其可用。


推荐阅读