1

単純な数学関数を実装したいとします。たとえば、 (C++17's) の再実装であるとしますstd::clamp。この関数は、数値、下限、および上限を取り、それらが定義する範囲外の場合、数値をそれらの境界の 1 つに設定します。具体的な数値型の場合、たとえばint、次のように記述します。

constexpr int clamp(int x, int lower_bound, int upper_bound)
{
    return x < lower_bound ? lower_bound : ( upper_bound < x ? upper_bound : x );
}

しかし、それがテンプレートの場合、おそらく標準で使用されるサンプル実装const&では、値ではなく が使用されていることがわかります。したがって、引用を簡単にするために、次のようにします。

template <typename T>
constexpr T clip(const T& x, const T& lower_bound, const T& upper_bound)
{
    return x < lower_bound ? lower_bound : ( upper_bound < x ? upper_bound : x );
}

私の質問は次のとおりです。

  • T単純な数値型であるに対して const 参照を使用する利点はありますか?
  • 同上、単一の数値をデータメンバーとしてラップする抽象的なものである型(たとえば、std::chrono期間)の場合は?
  • const&比較的単純な(constexpr?)、副作用のない数学的な関数の一般的なケースで、値を取る方が(そしてまったく)良い考えなのはなぜですか?

ノート:

  • const&たとえば、ある種の k 次元のベクトル型、またはboost::rationals やその他の数値のような型がある場合、 a を使用することが理にかなっていることに気付きました。それでも、コンパイラはコピーを最適化しないでしょうか?
  • 私は、任意の C++ 関数について質問しているわけではなく、そのパラメーターを値で受け取るだけでよいかどうかを尋ねているわけではありません。それは明らかに悪い考えです。
4

2 に答える 2

3
  • T単純な数値型であるに対して const 参照を使用する利点はありますか?

いいえ。

  • 同上、単一の数値をデータメンバーとしてラップする抽象的なものである型(たとえば、std::chrono期間)の場合は?

いいえ。

  • const&比較的単純な (constexpr?) 副作用のない数学的な関数の一般的なケースで、値よりも aを取る方が良いのはなぜですか?

動的割り当てを使用する bigint 型を想像してください。そのような型をコピーするのはコストがかかります。

  • コンパイラはコピーを最適化しませんか?

値をコピーしても副作用がないことを証明できる場合にのみ、関連するすべてのコードがコンパイラに表示されない限り、これを行うのは困難です。(したがって、bigint がたとえば GMP を使用している場合、運が悪いです。)

于 2016-10-12T21:38:13.143 に答える
2

T単純な数値型であるに対して const 参照を使用する利点はありますか?

いいえ、そうは思いませんが、罰則もありません。

同上、単一の数値をデータメンバーとしてラップする抽象的なものである型の場合(たとえば a std::chrono duration)?

同上。

const&一般的な場合に値を取得する方が良いのはなぜですか(そしてそれはまったく) ?

標準ライブラリのアルゴリズムは、基本型だけでなく、安価にコピーできないユーザー定義型にも対応するように設計されています。これらの型の場合、 a を使用するconst&と、コピーのペナルティを回避できますが、基本的な型の使用法が損なわれることはありません。

于 2016-10-12T21:30:58.787 に答える