私の理解では、根本的なC++暗黙コピーと移動コンストラクタの背後にある根拠? C++暗黙のコピーコンストラクタについて
T(T const& x) :
base1(x), base2(x) ... ,
var1(x.var1), var2(x.var2)...
{}
移動コンストラクタに似て&移動アサインも同様のパターンを以下のコピー。
はなぜそれは次のような定義されていませんでしたか?
T(T const& x) :
base1(static_cast<base1 const&>(x)),
base2(static_cast<base2 const&>(x)) ... ,
var1(x.var1), var2(x.var2)...
{}
例
Iは暗黙コピー/移動コンストラクタ/代入演算子、並びにいくつかの変換コンストラクタを持っていたクラスを有していました。私は仕事をいくつかの実装クラスに委任していました。
class common_work //common implementation of many work like classes
{
common_work(common_work const&) = default;
common_work(common_work&&) = default;// ... implicit constructors work for me.
//a forwarding constructor which can take many work like objects
template<class T, enable_if<work_like<T> > >
common_work(T&& x) { ... }
};
class work1 //one of the implementation
{
work1(work1 const&) = default;
work1(work1&&) = default; ...
common_work impl_;
};
work1
コピー/移動コンストラクタはwork
の別の種類に変換する[コードには示されていない] common_work
ためのコピー/移動のコンストラクタを呼び出す、およびコンストラクタは、他のコンストラクタによって使用された転送し、これは、微細でした。
次に、私はEBOとその他の理由でcommon_work
からwork1
を継承すると考えました。だから、新しいwork1
クラスが
class work1 : private common_work
{
work1(work1 const&) = default;
work1(work1&&) = default; ...
};
のように見えた。しかしとして、work1
はcommon_work
ためのコピー/移動コンストラクタがベースに派生からstatic_cast
を必要とするため、突然の転送コンストラクタは、より良い一致を得ていた、work_like
クラスです。
注:
- コピー構造はコンストラクタを転送することは何を必要としないながらコピーコンストラクタは、CONST添加を必要とするコンストラクタを転送トリガScott Meyersによって与えられた例の同様の種類があります。しかし、私は、その問題は間違ったクラス設計のために発生すると考えていますが、ここでの問題は、暗黙のコピー/移動中に基本クラスに渡される引数が完全に一致しないためです。
- 削除機能もオーバーロードの解決と原因エラーに参加しているため、正確に一致した場合、私は、ユニバーサル転送コンストラクタ/割り当てを書き、暗黙のものを削除することはできません。
- 私は現在溶液は、テンプレート引数として渡さCRTP、すなわち派生クラスタイプとして、それは
enable_if<and_<work_like<T>,not_<is_same<T,Derived> > > >
としてコンストラクタフィルタを転送にcommon_work
を作ることです。それ以外の場合は、work1
とstatic_cast
のコピー/移動コンストラクタ/代入を、バグ、エラーが発生しやすく、メンテナンスの危険性を明示的に基底クラスに書き込む必要があります。
おそらく、あなたは 'common_work'から派生した' T'を拒否するようにSFINAE制約を強化することでこれを回避できますか? –
それは私が現在していることです。 NOTEセクションの3番目の点を見てください。しかし、 'is_same'ではなく、 'is_same 、Derived> ' –
abir
、ごめんなさい。私は最後のノートを読んでいません:) –