我有以下代码,其中包含从以下位置复制的可变参数模板: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()函数并具有相同的值功能?
谢谢
诀窍是永远不要允许空的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;
}
为了补充@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 + ...);
}
- 这里需要
sum()
函数,以便我可以在处理最后一个可变参数成员时传入void
的返回值 - 是否可以避免编写此sum()
函数并具有相同的功能?
每次递归都需要停止条件。在使用可变参数模板(例如在此代码中)的递归的典型使用中,停止条件是主模板的不同重载。所以你无法完全摆脱这一点。
您当然可以用不同的条件替换停止条件。也许这个,也可用于总结不是默认构造的东西:
template <class T>
auto sum(T last) { return last; }
当然,除了递归可变参数模板之外,还有其他方法;这些方法可能不需要停止条件。
- 从
sum()
函数返回一个整数'0'会限制整个模板被整数使用 - 我可以扩展相同的模板来连接字符串吗?
不,因为非模板函数不知道先前的递归调用正在处理哪种类型。这可以通过使用我上面建议的“最后项目”停止条件来解决。