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

C++模板模板参数适配多参数与堆叠策略的实现问题

解决方案:适配策略堆叠与多模板参数的通用参数封装

问题根源

原有实现依赖模板模板参数(仅支持单类型参数的策略模板),无法兼容两种场景:

  • 堆叠后的策略是具体实例化类型(而非模板)
  • 多参数策略(如ImposedValueStrategy)包含非类型相关的模板参数(如std::ratio),无法直接适配单参数模板模板参数的要求

核心改造思路

将generic_parameter的模板参数从「模板模板参数」改为「具体策略类型」,同时通过统一策略接口和辅助推导函数实现类型自动推导,避免用户重复显式指定对象类型。


1. 重构通用参数模板

修改generic_parameter,使其接受任意已实例化的策略类型,要求策略必须暴露value_type(关联对象类型)和input_type(输入值类型):

#include <ratio>

template <typename Strategy>
class generic_parameter {
public:
    using value_type = typename Strategy::value_type;
    
    explicit generic_parameter(value_type& obj) : strategy_(obj) {}

    // 暴露策略核心接口:延迟填充值
    void set_value(typename Strategy::input_type val) {
        strategy_.apply(val);
    }

private:
    Strategy strategy_;
};

2. 统一策略接口定义

所有策略必须实现value_type、input_type和apply方法,确保与generic_parameter兼容。

基础策略示例(BasicStrategy)

template <typename T>
class BasicStrategy {
public:
    using value_type = T;
    using input_type = T;

    explicit BasicStrategy(T& obj) : obj_(obj) {}

    void apply(T val) {
        obj_ = val;
    }

private:
    T& obj_;
};

多参数复杂策略示例(ImposedValueStrategy)

通过绑定器模板预先固定非类型参数(如std::ratio),将多参数策略转换为单参数模板,适配自动推导:

template <typename Ratio, typename T>
class ImposedValueStrategy {
public:
    using value_type = T;
    // 输入值类型为原类型按比例缩放后的类型
    using input_type = typename std::ratio_multiply<Ratio, T>::type;

    explicit ImposedValueStrategy(T& obj) : obj_(obj) {}

    void apply(input_type val) {
        obj_ = static_cast<T>(val * Ratio::den / Ratio::num);
    }

private:
    T& obj_;
};

// 绑定器:预先固定Ratio参数,返回仅接受T的单参数模板
template <typename Ratio>
struct ImposedValueStrategyBinder {
    template <typename T>
    using type = ImposedValueStrategy<Ratio, T>;
};

堆叠策略示例(基础策略+比例缩放)

用装饰器模式实现策略堆叠,确保堆叠后的策略仍暴露标准接口:

template <typename InnerStrategy, typename Ratio>
class ScalingStrategy {
public:
    using value_type = typename InnerStrategy::value_type;
    using input_type = typename std::ratio_multiply<Ratio, typename InnerStrategy::input_type>::type;

    explicit ScalingStrategy(InnerStrategy inner) : inner_(std::move(inner)) {}

    void apply(input_type val) {
        using scaled_input = typename InnerStrategy::input_type;
        inner_.apply(static_cast<scaled_input>(val * Ratio::den / Ratio::num));
    }

private:
    InnerStrategy inner_;
};

// 辅助函数:自动推导内部策略类型,简化堆叠策略创建
template <typename InnerStrategy, typename Ratio>
ScalingStrategy<InnerStrategy, Ratio> scale_strategy(InnerStrategy inner, Ratio) {
    return ScalingStrategy<InnerStrategy, Ratio>(std::move(inner));
}

3. 辅助推导函数:简化调用

定义make_generic_parameter系列函数,利用C++11模板推导自动生成generic_parameter实例,无需用户显式指定对象类型:

// 适配单参数策略模板(如BasicStrategy)
template <template <typename> class Strategy, typename T>
generic_parameter<Strategy<T>> make_generic_parameter(T& obj) {
    return generic_parameter<Strategy<T>>(obj);
}

// 适配绑定后的多参数策略模板(如ImposedValueStrategyBinder的type)
template <template <typename> class Strategy, typename T>
generic_parameter<Strategy<T>> make_generic_parameter(T& obj) {
    return generic_parameter<Strategy<T>>(obj);
}

// 适配已实例化的堆叠策略
template <typename Strategy>
generic_parameter<Strategy> make_generic_parameter(Strategy&& strategy) {
    return generic_parameter<Strategy>(std::forward<Strategy>(strategy));
}

4. main函数简化调用示例

int main() {
    double d = 0.0;

    // 1. 基础策略调用:无需指定double类型
    auto param_basic = make_generic_parameter<BasicStrategy>(d);
    param_basic.set_value(10.0); // d = 10.0

    // 2. 多参数策略调用:仅需指定ratio,无需指定double类型
    auto param_imposed = make_generic_parameter<ImposedValueStrategyBinder<std::ratio<4,3>>::type>(d);
    param_imposed.set_value(12.0); // d = 12.0 * 3/4 = 9.0

    // 3. 堆叠策略调用:基础策略+2倍缩放,无需手动指定类型
    auto scaled_strat = scale_strategy(BasicStrategy<double>(d), std::ratio<2,1>());
    auto param_scaled = make_generic_parameter(std::move(scaled_strat));
    param_scaled.set_value(5.0); // 内部先转换为5.0*1/2=2.5,再赋值给d

    return 0;
}

内容的提问来源于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 11:10:19