不完全是一个问题,尽管我一直在思考如何通过风格更优雅地编写这样的代码,同时充分利用新的 c++ 标准等。这是示例
将斐波那契数列返回到一个容器中,最多 N 个值(对于那些不擅长数学的人,这只是将前两个值相加,前两个值等于 1。即 1,1,2,3,5,8,13 , ...)
从主运行的例子:
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) 相同但使用 rvalue && 而不是 & 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++ 代码?使用右值引用 (&&),移动语义似乎就位并且没有进行不必要的复制,这在时间上做了一个小改进(由于 future 的实时应用程序开发,这对我来说很重要)。一些具体的“问题”是
a) 将容器(在我的示例中是 vector )作为参数传递给函数并不是真正应该如何使用右值的优雅解决方案。这个事实是真的吗?如果是的话,右值如何在上面的例子中真正显示它的光?
b) coll.resize(N); 调用和 N=1 情况,有没有办法避免这些调用,从而为用户提供一个简单的界面只使用函数而不动态创建 vector 的大小。模板元编程可以在这里使用,以便在编译时为 vector 分配特定大小吗? (即 running_fibonacci_seq<30000000>)因为数字可能很大是否需要使用模板元编程,如果可以的话我们可以使用 this (link)还有
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
最佳答案
由于“引用折叠”,此代码不使用右值引用或移动任何内容:
template <typename T, typename INT_TYPE>
void running_fibonacci_seq(T&& coll, const INT_TYPE& N);
running_fibonacci_seq(vec,30000000);
当您认识到这一点时,您所有的问题(以及现有的评论)都变得毫无意义。
关于c++ - 从函数 : optimizing speed and modern style 返回容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14162738/