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

C++17类模板部分实参推导:如何混合显式指定与自动推导参数

结论

C++17标准下不支持类模板部分显式指定参数、部分推导的用法,推导指南(deduction guides)也无法实现该需求。

核心规则说明

  • C++17的类模板实参推导(CTAD)只有在完全省略模板尖括号时才会触发,只要你在尖括号内写了任意数量的参数,编译器就会要求你提供全部模板参数,不会启动推导流程。
  • 你目前了解的「CTAD要么全显式指定、要么全推导」的规则是完全正确的,推导指南仅作用于全推导的场景,无法解决部分指定的需求。

C++17下更优雅的替代方案

不需要写外部构造函数,你可以在类内实现静态工厂方法,封装性更好:

template<typename T1, typename T2>
struct S
{
    T2 t2;

    S(const T2& _t2) : t2{_t2} {}

    // 静态工厂方法,利用函数模板的部分推导特性
    template<typename U1, typename U2>
    static S<U1, U2> create(const U2& t2) {
        return S<U1, U2>{t2};
    }

    void operator()(const T1& t1)
    {
        std::cout << t1 << ", " << t2 << '\n';
    }
};

int main()
{
    // 调用方式更简洁,和类绑定不需要额外引入外部函数
    auto s2 = S::create<int>(3.14);
    std::function<void(int)> func2 = s2;
    func2(42);
}

C++20及以上版本的原生支持

从C++20开始,类模板实参推导已经支持部分显式指定前缀参数,你期望的写法可以直接生效:

// C++20及以上可以直接这么写,不需要任何工厂函数
S<int> s2 {3.14}; // T1显式指定为int,T2从3.14推导为double

内容的提问来源于stack exchange,提问作者Zamfir Yonchev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:24:00