假设我有一个可变数量的参数,我想将它们相乘。我想到的第一种方法是递归算法:
template<typename Head>
u64 Multiply(Head head) const
{
return head;
}
template<typename Head, typename... Tail>
u64 Multiply(Head head, Tail... tail) const
{
return head * Multiply(tail...);
}
但后来我看到了这个伎俩:
// u32 and u64 are 32 and 64 bit unsigned integers.
template<typename... T>
u64 Multiply(T... args)
{
u64 res = 1;
for (const u32& arg: {args...})
res *= arg;
return res;
}
第二个看起来对我来说更好。更容易阅读。但是,这如何影响性能呢?有什么东西被复制了? {args...}
首先做了什么?有更好的方法吗?
我可以访问C ++ 14。
编辑要清楚:它是关于运行时乘法,而不是编译时间。
更清楚:我不想计算整数(虽然那是我当前的应用程序),但我发现的算法专门用于整数。
更多:参数属于同一类型。没有这种限制的算法会非常有趣,但也许是针对不同的问题。
答案 0 :(得分:4)
这里有多个问题:
docker exec -it <CONTAINER_ID> ip add show eth0
?好吧,它为参数的常见类型创建{ args... }
(假设有一个)。但是,您可能希望将值与std::initializer_list<T>
一起使用,而不是使用固定类型。std::common_type_t<T...>
,但是,它需要C ++ 17。如果至少有一个参数可以省略return (args * ... * 1);
:如果存在一个可变参数的空列表,则可以避免编译时错误。答案 1 :(得分:1)
代码
template<typename... T>
u64 Multiply(T... args)
{
u64 res = 1;
for (const u32& size : {args...})
res *= size;
return res;
}
对我来说有点神秘:-)为什么我们有类型为T的模板参数,在我们使用的方法中我们使用了修复大小值?变量名size
看起来非常模糊,因为这个var与任何类型的大小无关。如果将浮点数据提供给模板,则在内部使用整数类型也不是有效的假设。
好的,但要回答你的问题:
第一个可用于您放入模板功能的所有类型。第二个使用固定(无符号整数)类型,如果我看到模板本身的声明,这不是我所期望的。
我现在学到的两个版本都可以constexpr
:-)并且可以很好地进行编译时计算。
回答你的评论中的问题:
{args...}
扩展为:
{ 1,2,3,4}
它只是一个“数组”(std :: std :: initializer_list),只有在所有元素具有相同类型时才有效。
所以
for (const u32& size : {args...})
简单地遍历数组。