C++泛型类模板特化后成员变量与方法的使用疑问
C++类模板特化相关疑问解答
问题背景
现有两个文件a.h和a.cpp,代码如下:
a.h 中的泛型类模板
//File a.h template< typename V, typename C > class Example{ public: void foo(void){ // 使用类的私有成员变量 gmp = new C; tmp = new V; tmp->something(...); } private: V tmp; C gmp; };
a.cpp 中的部分特化类
//File a.cpp template< typename C > class Example<int, C>{ // 希望复用泛型版本的foo方法,不在此重新定义 // 尝试定义fun(),期望使用泛型Example类中的gmp变量 void fun(void){ print(gmp); print(tmp); } private: int tmp; };
疑问解答
1. 泛型类的foo方法会使用哪个tmp变量?
泛型类Example<V,C>的foo方法只会访问自身私有成员里的V tmp。你在a.cpp中定义的是部分特化类Example<int,C>,它和原泛型模板是完全独立的类型,两者不存在成员共享或互相影响的关系——泛型模板的代码根本不知道特化类的存在,自然只会访问自己的成员。
另外注意:你代码里的foo有编译错误——tmp是V类型的对象,但你写了tmp = new V;,这是把指针赋值给非指针类型,必须修正(比如改成tmp = V();,或者把成员类型改成V* tmp;)。
2. 特化类的fun方法能否使用泛型类中的gmp变量?
不能。部分特化的Example<int,C>是全新的类定义,它和原泛型模板没有继承关系,也不会自动继承原模板的成员。特化类里只声明了int tmp,没有gmp成员,直接写print(gmp)会触发编译错误,编译器找不到这个变量。
3. 如何让fun方法使用gmp变量,以及泛型类中的V类型tmp变量?
要实现这个需求,有两种可行方案:
方案一:让特化类继承泛型模板
通过继承让特化类获得原模板的成员,同时调整访问权限或声明友元来访问私有成员:
修改a.h的泛型类:
//File a.h template< typename V, typename C > class Example{ // 声明特化类为友元,允许它访问私有成员 template<typename> friend class Example; public: void foo(void){ // 修正指针赋值问题(以对象类型为例) tmp = V(); gmp = C(); } protected: // 或者保持private+友元声明 V tmp; C gmp; };
修改a.cpp的特化类:
//File a.cpp template< typename C > class Example<int, C> : public ::Example<int, C>{ public: // 引入泛型类的foo方法到当前作用域 using ::Example<int,C>::foo; void fun(void){ print(gmp); // 直接访问继承来的gmp print(this->tmp); // 访问继承来的int tmp,若特化类有同名成员需用this->区分 } private: // 若不需要特化类自己的tmp,可删除;若保留需改名避免冲突,比如int local_tmp; // int tmp; };
方案二:抽离公共逻辑到独立模板函数,特化类显式声明成员
把原模板foo的逻辑抽成独立函数,特化类自己声明所需成员并复用该逻辑:
修改a.h:
//File a.h template<typename V, typename C> void example_foo(Example<V,C>* obj){ // 复用原foo的逻辑 obj->tmp = V(); obj->gmp = C(); } template< typename V, typename C > class Example{ public: void foo(void){ example_foo(this); } private: V tmp; C gmp; // 让外部函数能访问私有成员 template<typename, typename> friend void example_foo(Example<V,C>*); };
修改a.cpp的特化类:
//File a.cpp template< typename C > class Example<int, C>{ public: // 复用泛型的foo逻辑 void foo(void){ example_foo(this); } void fun(void){ print(gmp); // 特化类自己声明的gmp成员 print(tmp); // 特化类自己的int tmp(对应原模板的V类型tmp,此处V=int) } private: int tmp; C gmp; // 显式声明gmp成员 };
内容的提问来源于stack exchange,提问作者Daniele Caliandro
相关产品推荐
相关产品推荐

