模板参数默认值与推导的模板参数相关

J.M*_*J.M 4 c++ templates c++11 template-argument-deduction

我知道这个问题与这篇文章非常相似,但是引用的文章是关于模板参数推导的。这里我的问题是关于函数模板参数推导。

我目前有以下代码段,它使用户能够指定方法应使用的算法来计算某些值。(由于各种与此处不相关的原因,使用策略模式在这种情况下不适用)

#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;
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以简化“Func()”的接口,以便在不使用“BasicStrategy”的情况下免除用户指定冗余类型的麻烦。例如,“理想”接口将如下所示(我意识到这是不可能的):

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

    Func(i);
    Func(d);

    Func<ComplexStrategy>(i);
    Func<ComplexStrategy>(d);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然,我可以这样声明 Func()

template<typename STRATEGY, typename T>
void Func(T& i_Input)
Run Code Online (Sandbox Code Playgroud)

这不需要用户指定类型 T 两次,但是,这会阻止我为该方法分配默认策略,这会破坏许多现有代码并使其整体可读性较差。

这个问题有一个干净的解决方案吗?或者这是我必须在两个选项之间做出的选择?

Mat*_*rün 6

您可以使用模板模板参数来实现您想要的效果:

template<template <typename> typename Strategy = BasicStrategy, typename T>
void Func(T& i_Input)
{
    Strategy<T> MyStrategy(i_Input);
}
Run Code Online (Sandbox Code Playgroud)

这样你提到的理想的方法就可以工作:https://godbolt.org/z/aosPzqa3r