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

函数模板参数推导:简化依赖推导参数的默认模板参数调用

问题描述

我遇到的问题和另一篇讨论类模板实参推导的帖子类似,但本文聚焦于函数模板实参推导。

目前我有如下代码,允许用户指定方法计算值时使用的算法(因多种无关原因,此处不适用策略模式):

#include <iostream>
#include <typeinfo>
template<typename T>
class BasicStrategy
{
    public:
    BasicStrategy(T& i_Input)
    {
        std::cout << "Applying Basic Strategy to type : " << typeid(T).name() << " With value : " << i_Input <<std::endl;
    }
};

template<typename T>
class ComplexStrategy
{
    public:
    ComplexStrategy(T& i_Input)
    {
        std::cout << "Applying Complex Strategy to type : " << typeid(T).name() << " With value : " << i_Input <<std::endl;
    }
};

template<typename T, typename STRATEGY = BasicStrategy<T>>
void Func(T& i_Input)
{
    STRATEGY MyStrategy(i_Input);
}


int main()
{
    int i = 12;
    double d = 24;
    
    Func(i);
    Func(d);

    Func<int, ComplexStrategy<int>>(i);
    Func<double, ComplexStrategy<double>>(d);
    return 0;
}

我希望简化Func()的接口,让用户在不使用BasicStrategy时无需指定冗余类型,理想的调用方式如下:

int main()
{
    int i = 12;
    double d = 24;

    Func(i);
    Func(d);

    Func<ComplexStrategy>(i);
    Func<ComplexStrategy>(d);
    return 0;
}

如果把Func声明为:

template<typename STRATEGY, typename T>
void Func(T& i_Input)

这样虽然无需重复指定T,但无法设置默认策略,会破坏大量现有代码且降低可读性。

请问是否存在简洁的解决方案,还是只能在这两种方案之间做选择?


解决方案

可以通过模板模板参数实现需求,既保留默认策略,又支持简化调用:

#include <iostream>
#include <typeinfo>

template<typename T>
class BasicStrategy
{
public:
    BasicStrategy(T& i_Input)
    {
        std::cout << "Applying Basic Strategy to type : " << typeid(T).name() << " With value : " << i_Input << std::endl;
    }
};

template<typename T>
class ComplexStrategy
{
public:
    ComplexStrategy(T& i_Input)
    {
        std::cout << "Applying Complex Strategy to type : " << typeid(T).name() << " With value : " << i_Input << std::endl;
    }
};

// 主模板:使用模板模板参数,默认策略为BasicStrategy
template<template<typename> typename STRATEGY = BasicStrategy, typename T>
void Func(T& i_Input)
{
    STRATEGY<T> MyStrategy(i_Input);
}

// 重载版本:兼容原有的调用方式(避免破坏现有代码)
template<typename T, typename STRATEGY>
void Func(T& i_Input)
{
    STRATEGY MyStrategy(i_Input);
}

int main()
{
    int i = 12;
    double d = 24;
    
    // 原有调用方式保持不变
    Func(i);
    Func(d);
    
    // 简化后的调用方式
    Func<ComplexStrategy>(i);
    Func<ComplexStrategy>(d);
    
    // 兼容原来的显式指定两个参数的调用
    Func<int, ComplexStrategy<int>>(i);
    return 0;
}

说明

  1. 主模板使用模板模板参数template<typename> typename STRATEGY,用户只需传入策略模板本身(如ComplexStrategy),函数会自动推导T并实例化STRATEGY<T>。
  2. 保留原模板的重载版本,确保现有代码无需修改即可正常工作。
  3. 这种方式同时满足默认策略需求和简化调用需求,无需在两种方案间妥协。

内容的提问来源于stack exchange,提问作者J.M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 07:55:19