不完全是一个问题,虽然只是我一直在思考如何通过风格更优雅地编写这样的代码,同时充分利用新的 c++ 标准等。这是示例
将斐波那契序列返回到一个容器中最多 N 个值(对于那些不倾向于数学的人,这只是将前两个值相加,前两个值等于 1。即 1,1,2,3,5,8,13,.. .)
示例从 main 运行:
std::vector<double> vec;
running_fibonacci_seq(vec,30000000);
1)
template <typename T, typename INT_TYPE>
void running_fibonacci_seq(T& coll, const INT_TYPE& N)
{
coll.resize(N);
coll[0] = 1;
if (N>1) {
coll[1] = 1;
for (auto pos = coll.begin()+2;
pos != coll.end();
++pos)
{
*pos = *(pos-1) + *(pos-2);
}
}
}
2) 相同,但使用右值&& 而不是 & 1.e。
void running_fibonacci_seq(T&& coll, const INT_TYPE& N)
编辑:正如下面评论的用户所注意到的,右值和左值在时间上没有任何作用——由于评论中讨论的原因,速度实际上是相同的
N = 30,000,000 的结果
Time taken for &:919.053ms
Time taken for &&: 800.046ms
首先,我知道这确实不是一个问题,但是其中哪个或哪个是最好的现代 C++ 代码?使用右值引用 (&&) 似乎移动语义已经到位,并且没有制作不必要的副本,这在时间上做了一个小的改进(对我来说很重要,因为未来的实时应用程序开发)。一些具体的“问题”是
a) 将容器(在我的示例中是向量)作为参数传递给函数并不是真正应该如何使用右值的优雅解决方案。这是真的吗?如果是这样,在上面的示例中,右值如何真正显示它的轻量级?
b) coll.resize(N); 调用和N=1的情况,有没有办法避免这些调用,所以给用户一个简单的界面,只使用函数而不动态创建向量的大小。可以在这里使用模板元编程,以便在编译时为向量分配特定大小吗?(即running_fibonacci_seq<30000000>)因为数字可能很大,是否需要使用模板元编程,如果可以的话,我们也可以使用这个(链接)
c) 有没有更优雅的方法?我有一种感觉 std::transform 函数可以通过使用lambdas来使用,例如
void running_fibonacci_seq(T&& coll, const INT_TYPE& N)
{
coll.resize(N);
coll[0] = 1;
coll[1] = 1;
std::transform (coll.begin()+2,
coll.end(), // source
coll.begin(), // destination
[????](????) { // lambda as function object
return ????????;
});
}
[1] http://cpptruths.blogspot.co.uk/2011/07/want-speed-use-constexpr-meta.html