C++11中如何定义带继承的模板模板类型?
问题:C++11中如何基于模板基类定义派生类,同时访问包装类内部类型的静态方法
我想要定义一个派生类,使其为模板基类使用模板模板类型。请问这是否可行?若可行,语法是什么?我尝试了多种方式均未成功,相关代码如下:
#include <iostream> template <typename U> struct Wrapper {}; template <typename U> struct Base {}; // This Works, define a template template type class template<class> struct Other; template<template<typename T> typename W, typename T> struct Other<W<T>> {}; // How do I define this? template<template<typename T> typename W, typename T> struct Derived : public Base<W<T>> {}; using namespace std; int main() { Wrapper<float> w; Base<int> b; Other<Wrapper<int>> o; Derived<Wrapper<int>> d; // fails to compile return 0; }
背景说明:我现有可用代码中存在Derived<U>,其中U是包装类W<T>。原本无需用模板模板类型定义Derived<W<T>>,Derived<U>即可满足需求。但现在我需要在Derived作用域内访问T的静态方法,且目前只能使用C++11。
解决方案
一、核心问题分析
你当前的代码编译失败有两个关键原因:
- 模板参数不匹配:你定义的
Derived要求两个模板参数(一个模板模板参数W,一个类型参数T),但实例化时只传了一个具体类型Wrapper<int>,两者无法匹配。 - C++11语法限制:C11中模板模板参数的声明必须用
class而非typename,你代码里的template<typename T> typename W是C17才支持的写法,在C++11中会直接报错。
结合你需要保留Derived<U>原有用法的需求,类型萃取是最兼容的解决方案。
二、具体实现方案
1. 定义类型萃取模板,提取包装类内部的T
通过模板偏特化,从W<T>这类包装类型中提取出内部的T类型:
template <typename U> struct ExtractInnerType; // 偏特化:匹配所有单参数模板的实例化类型 template <template <typename> class W, typename T> struct ExtractInnerType<W<T>> { using type = T; };
2. 修改Derived类,兼容原有用法并访问T的静态方法
继承Base<U>的同时,用类型萃取获取T,进而访问其静态方法:
template <typename U> struct Derived : public Base<U> { void callStaticMethod() { // 提取出包装类内部的T类型 using T = typename ExtractInnerType<U>::type; // 调用T的静态方法(示例假设T有static void func()) T::func(); } };
3. 完整可编译示例(兼容C++11)
#include <iostream> template <typename U> struct Wrapper {}; template <typename U> struct Base {}; // 类型萃取模板 template <typename U> struct ExtractInnerType; template <template <typename> class W, typename T> struct ExtractInnerType<W<T>> { using type = T; }; // 修改后的Derived template <typename U> struct Derived : public Base<U> { void demo() { using T = typename ExtractInnerType<U>::type; // 示例:访问T的静态特性,这里用类型构造演示 std::cout << "Accessing type T: " << T(42) << std::endl; } }; // 测试用的带静态方法的类型 struct MyType { static void func() { std::cout << "MyType static method called" << std::endl; } }; int main() { Wrapper<float> w; Base<int> b; // 原有用法完全兼容 Derived<Wrapper<int>> d1; d1.demo(); // 测试自定义类型的静态方法调用 Derived<Wrapper<MyType>> d2; using T = typename ExtractInnerType<Wrapper<MyType>>::type; T::func(); return 0; }
三、备选方案:直接使用模板模板参数(不兼容原有用法)
如果你不需要保留Derived<U>的原有写法,也可以修正语法后直接使用模板模板参数实例化,但会破坏现有代码兼容性:
// 修正C++11语法后的Derived template<template<typename T> class W, typename T> struct Derived : public Base<W<T>> { void callStaticMethod() { // 直接使用T访问静态方法 T::func(); } }; // 实例化方式需改为: Derived<Wrapper, int> d;
内容的提问来源于stack exchange,提问作者DisplayName
相关产品推荐
相关产品推荐

