メンバー変数、コピー可能および移動可能なタイプのそれぞれ、および対応するセッター関数をX
持つクラスについて考えてみます。C ++ 98では、の定義は次のようになります。N
N
X
class X
{
public:
void set_a(A const& a) { _a = a; }
void set_b(B const& b) { _b = b; }
...
private:
A _a;
B _b;
...
};
上記のクラスのセッター関数はX
、左辺値と右辺値の両方の引数にバインドできます。実際の引数によっては、これにより一時的なものが作成され、最終的にはコピーの割り当てが発生する可能性があります。このため、コピーできないタイプはこのデザインではサポートされていません。
C ++ 11では、移動セマンティクス、完全な転送、およびユニバーサル参照(Scott Meyersの用語)があり、次のように書き直すことで、セッター関数をより効率的かつ一般的に使用できます。
class X
{
public:
template<typename T>
void set_a(T&& a) { _a = std::forward<T>(a); }
template<typename T>
void set_b(T&& b) { _b = std::forward<T>(b); }
...
private:
A _a;
B _b;
...
};
ユニバーサル参照は、/ non -、/ non- const
、および一般に任意の変換可能なタイプにバインドできるため、一時的なものの作成を回避し、値をに直接渡すことができます。コピー不可能な移動可能なタイプがサポートされるようになりました。おそらく望ましくないバインディングは、を介して、またはを介して排除できます。const
volatile
volatile
operator =
static_assert
std::enable_if
だから私の質問は:設計ガイドラインとして、C ++ 11のすべての(たとえばほとんどの)セッター関数は、ユニバーサル参照を受け入れる関数テンプレートとして作成する必要がありますか?
より厄介な構文と、これらのセッター関数でコードを記述するときにIntellisenseのようなヘルパーツールを使用できないことは別として、「可能な場合はいつでもユニバーサル参照を受け入れる関数テンプレートとしてセッター関数を書く」という仮定の原則に関連する欠点はありますか?