You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用typedef、别名及using获取基类模板参数类型?

不使用typedef/别名/using获取基类模板参数类型的方案

可以利用基类中doSomething()纯虚函数的返回类型进行编译期推导,完全不需要在A中额外定义using Type=T,也能拿到对应的模板参数类型。

简洁实现(利用decltype推导)

直接通过decltype结合std::declval提取doSomething()的返回类型,这就是A的模板参数类型:

#include <iostream>
#include <utility>

template <class T>
class A {
public:
    virtual T doSomething() const = 0;
};

template <class T>
class B : public T {
    // 推导基类A的模板参数类型
    using Type = decltype(std::declval<const T&>().doSomething());

public:
    Type doSomething() const override {
        return 0;
    }

    Type value;
};

class C : public A<double> {
public:
};

class D : public A<int> {
public:
};

int main() {
    B<C> b1;
    B<D> b2;
    
    std::cout << b1.doSomething() << "\n";
    std::cout << b2.doSomething() << "\n";
}
  • std::declval<const T&>()用来在编译期模拟一个const T类型的引用,无需实际构造对象。
  • decltype会提取doSomething()调用表达式的类型,也就是A的模板参数T。

完全不使用using的写法

如果要求连B中的using都不能用,直接在需要类型的位置写decltype表达式即可:

template <class T>
class B : public T {
public:
    decltype(std::declval<const T&>().doSomething()) doSomething() const override {
        return 0;
    }

    decltype(std::declval<const T&>().doSomething()) value;
};

备选方案:模板特化提取类型

也可以通过模板特化结合SFINAE来检测派生类的基类参数,不过这种写法更繁琐,适合更复杂的场景:

#include <iostream>
#include <type_traits>

template <class T>
class A {
public:
    virtual T doSomething() const = 0;
};

// 辅助模板:检测类型是否继承自A<V>并提取V
template <typename U>
struct ExtractAArg {
private:
    // 匹配继承自A<V>的类型
    template <typename V>
    static V test(const A<V>*);
    // 默认匹配
    static void test(...);
public:
    using Type = decltype(test(static_cast<const U*>(nullptr)));
};

template <class T>
class B : public T {
    using Type = typename ExtractAArg<T>::Type;

public:
    Type doSomething() const override {
        return 0;
    }

    Type value;
};

class C : public A<double> {
public:
};

class D : public A<int> {
public:
};

int main() {
    B<C> b1;
    B<D> b2;
    
    std::cout << b1.doSomething() << "\n";
    std::cout << b2.doSomething() << "\n";
}

内容的提问来源于stack exchange,提问作者Miroslav Krajcir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:00:29