【问题标题】:Variadic Templates - Recursive function - Last variadic member可变参数模板 - 递归函数 - 最后一个可变参数成员
【发布时间】:2019-03-06 15:20:16
【问题描述】:

我有以下代码,其中包含从以下位置复制的可变参数模板: https://www.youtube.com/watch?v=iWvcoIKSaoc@41:30

auto sum() { return 0; }

template<typename Head, typename... Tail>
auto sum(Head head, Tail... tail)
{
    return head+sum(tail...);
}

int main() {
    cout<< sum(1,2.4) << endl;
    //cout<< sum("hello ", "world") << endl;
    return 0;
}

我有两个问题: 1. 这里需要 sum() 函数,以便在处理最后一个可变参数成员时可以有一个传入的 void 的返回值 - 是否可以避免编写这个 sum() 函数并具有相同的功能?

  1. 从 sum() 函数返回整数 '0' 会限制整数使用整个模板 - 我可以扩展同一个模板来连接字符串吗?

谢谢

【问题讨论】:

  • C++14 标签是否意味着你不想听到 C++17 折叠表达式?
  • 不 - 我可以使用 C++17

标签: c++ variadic-templates typetraits


【解决方案1】:

为了补充@GuillaumeRacicot 的答案,我更喜欢使用if constexpr 来结束递归,这是c++17 功能。

template<typename Head, typename Second, typename... Tail>
auto sum(Head head, Second second, Tail... tail)
{ 
    if constexpr(sizeof...(tail) > 0)
      return head + sum(second, tail...);
    return head + second;
}

你也可以考虑折叠表达式:

template<typename ...Pack>
auto sum(Pack... args) {
    return (args + ...);
}

【讨论】:

【解决方案2】:

诀窍是永远不允许空的sum() 调用,并将sum(last) 视为最后一次递归:

template<typename Last>
auto sum(Last last) {
    return last;
}

template<typename Head, typename Second, typename... Tail>
auto sum(Head head, Second second, Tail... tail)
{
    return head + sum(second, tail...);
}

int main() {
    cout<< sum(1,2.4) << endl;
    cout<< sum("hello ", "world") << endl;
    return 0;
}

Live example

【讨论】:

    【解决方案3】:
    1. 这里需要sum() 函数,这样我可以在处理最后一个可变参数成员时获得传入的void 的返回值 - 是否可以避免编写此sum() 函数并具有相同的功能?

    每个递归都需要一个停止条件。在带有可变参数模板的递归的典型使用中(例如在此代码中),停止条件是主模板的不同重载。所以你不能完全摆脱它。

    您当然可以将停止条件替换为其他条件。也许这个也适用于对不可默认构造的事物求和:

    template <class T>
    auto sum(T last) { return last; }
    

    当然,除了递归可变参数模板之外,还有其他方法。这种方法可能不需要停止条件。

    1. sum() 函数返回整数“0”会限制整数使用整个模板 - 我可以扩展同一个模板来连接字符串吗?

    不,因为非模板函数不知道之前的递归调用处理的是哪种类型。这可以通过使用我上面建议的“最后一项”停止条件来解决。

    【讨论】:

    • return {}; 的解决方案如何工作?我不能让它工作:ideone.com/vrCXSb
    • @mch 当然,这是我的错误。固定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    相关资源
    最近更新 更多