完全な質問ではありませんが、スタイルによってそのようなコードをよりエレガントに記述し、同時に新しい c++ 標準などを十分に活用する方法について熟考していたものです。例を次に示します。
フィボナッチ数列を最大 N 個の値のコンテナーに戻します (数学的に傾いていないものについては、これは前の 2 つの値を加算し、最初の 2 つの値が 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) 同じですが、& 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) コンテナー (私の例では vector でした) をパラメーターとして関数に渡すことは、右辺値が実際にどのように使用されるべきかについての洗練された解決策ではありません。この事実は本当ですか?もしそうなら、右辺値は上記の例でそれが軽いことを実際にどのように示しますか?
b) coll.resize(N); 呼び出しとN=1の場合、これらの呼び出しを回避する方法はありますか?そのため、ユーザーはベクトルのサイズを動的に作成せずに関数のみを使用する単純なインターフェイスを使用できます。コンパイル時にベクトルが特定のサイズで割り当てられるように、テンプレートのメタプログラミングをここで使用できますか? (ie running_fibonacci_seq<30000000>) 数値が大きくなる可能性があるため、テンプレート メタプログラミングを使用する必要がある場合は、これ (リンク)も使用できます。
c) もっと洗練された方法はありますか? std ::transform 関数は、ラムダを使用して使用できると感じています。
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