特別なメンバー関数が呼び出されたときにログに記録する単純なラッパー テンプレート クラスに取り組んでいます。これらの関数は、追加のロギング関連タスクを実行するため、デフォルトにすることはできません。
template <typename T>
struct logger {
logger(T const& value) : value_(value) { /*...log...*/ }
logger(T&& value) : value_(std::move(value)) { /*...log...*/ }
logger(logger const& other) : value_(other.value_) { /*...log...*/ }
logger(logger&& other) : value_(std::move(other.value_)) { /*...log...*/ }
T value_;
};
残念ながら、ラップされた型が右辺値参照の場合、コピー コンストラクターは次のエラー メッセージでコンパイルに失敗します。
エラー: 'int' 左辺値を 'int&&' にバインドできません</p>
その理由は、暗黙のコピー コンストラクターが右辺値参照メンバーに対して多少異なる動作をするためです。
[class.copy 12.8/15] 非共用体クラスの暗黙的に定義されたコピー/移動コンストラクターは、
X
そのベースとメンバーのメンバーごとのコピー/移動を実行します。[...]x
コンストラクターのパラメーター、または移動コンストラクターの場合は、パラメーターを参照する xvalue のいずれかになります。各ベースまたは非静的データ メンバーは、そのタイプに適した方法でコピー/移動されます。
- メンバーが配列の場合、各要素は の対応するサブオブジェクトで直接初期化され
x
ます。- メンバー m が右辺値参照型を持つ場合
T&&
、それは で直接初期化されstatic_cast<T&&>(x.m)
ます。- それ以外の場合、ベースまたはメンバーは の対応するベースまたはメンバーで直接初期化され
x
ます。
これは私の質問につながります:メンバーとして右辺値参照を使用する場合でも、暗黙的に定義されたcopy-constructorとして動作する汎用のcopy-constructorをどのように作成するのですか?
この特定のケースでは、 rvalue-references の特殊化を追加できます。ただし、単一のメンバーに制限されず、コードの重複を導入しない汎用ソリューションを探しています。