提问者:小点点

变量模板vs使用元组在参数中添加不同的数据对


以下主要代码可以正常工作

    string hello = "Hello ";
    string world = "templates!";

    cout << "var template add: ";


    cout << setprecision(2) <<
        var_template_add(5, 4, 5.5, 4.0);

用于以下模板生成器代码和变量函数

template <typename T> 
auto add(T a, T b) {
    return a + b;
}


template <typename T, typename... Rest> 
auto var_template_add(T first, T second, Rest... others) {
    return first + second + add (others...);
}

但如果再添加两个字符串参数,如下所示

var_template_add(5, 4, 5.5, 4.0, hello, world);

编译器错误捕获“找不到匹配的重载函数”。

再一次,

string hello = "Hello ";
string world = "templates!";
cout << "strings add result: " << setprecision(2) << add(hello, world) << endl;

可以工作,如果我写模板函数“添加”如下:

template <typename T1, typename T2>
auto add(T1 a, T2 b) {
    return a + b;
}

我的问题是,我怎么才能排队

var_template_add(5, 4, 5.5, 4.0, hello, world);

不像上面那样编写另一个添加函数就可以工作吗?!

请注意,我可以使用元组来传递这个值,但现在,我只想远离它。 有什么想法/改进吗?


共3个答案

匿名用户

当前调用工作的唯一方法是var_template_add返回单个类型,因此它需要是一个字符串。

相反,您可以在函数内部编写cout,因此您只需要:

template <typename T, typename... Rest> 
auto var_template_add(T first, T second, Rest... others) {
    cout << setprecision(2) << (first + second) << " ";
    if constexpr (sizeof...(others)) var_template_add(others...);
}

这是一个演示。

请注意,如果constexpr在C++17之前没有,因此在这种情况下,有一个额外的重载作为基本情况是一个不错的选择。

匿名用户

在C++11中,这可以通过使用一些模板递归来完成。 这本身并不需要添加任何新函数--只需重命名一个现有函数并更改一个。

其思想是递归调用var_template_add,直到最后得到2个参数,然后将这两个参数加在一起:

// rename'add' to 'var_template_add'. Use this as recursive base-case.
template <typename T> 
auto var_template_add(T first, T second) 
  -> decltype(first + second)
{
    return first + var_template_add(add, others...);
}

// adds first argument and delegates 'second' and 'others...' to the next 'var_template_add'
template <typename T, typename... Rest> 
auto var_template_add(T first, T second, Rest... others) 
  -> decltype(first + var_template_add(second, others...))
{
    return first + var_template_add(second, others...);
}

对于2个参数,它将调用第一个重载。 对于3个或更多的参数,它将调用第二个参数,该参数将递归地调用下一个var_template_add,直到最终调用第一个参数。

注意:这个答案是因为这个问题被标记为C++11--但是请注意,您使用的auto返回类型不带尾随返回类型实际上是C++14,而不是C++11。

如果您有C++17,则可以使用可变折叠表达式更容易地完成此操作:

template <typename T, typename...Rest>
auto var_template_add(T first, T second, Rest...others)
{
    return first + second + (... + others);
}

匿名用户

变量模板定义要求变量计数的所有参数具有相同的类型。 即。 你不能把float和string混在一起。 因此,您的函数var_template_add()需要2个类型为T的参数,然后需要0个或更多表示为REST的其他类型的参数,但您需要向它提供2个整数,2个浮点和2个字符串。

注意:变量模板只能接受1个变量数的参数,并且必须位于参数列表的最末尾。 因此,如果您希望能够像在您的示例中那样进行调用,那么您可以将您的模板更改为如下内容例如:

auto var_template_add(T first, T second, R third, R fourth, Rest... others) {//...