const
type のインスタンスへの参照をB
classに格納する必要がある場合は、インスタンスの有効期間がインスタンスの有効期間を超えているA
ことを確認したいはずです。A
B
B b{};
A a1{b}; // allowed
A a2{B{}}; // should be denied
B const f() { return B{}; } // const result type may make sense for user-defined types
A a3{f()}; // should also be denied!
これを可能にするに= delete;
は、右辺値 ( と の両方) を受け入れることができるすべてのコンストラクターのオーバーロードを明示的に行う必要がconst &&
あり&&
ます。これを達成するには、コンストラクターのバージョン= delete;
のみにする必要があります。const &&
struct B {};
struct A
{
B const & b;
A(B const & bb) : b(bb) { ; } // accepts only `B const &` and `B &`
A(B const &&) = delete; // prohibits both `B &&` and `B const &&`
};
このアプローチにより、コンストラクターにあらゆる種類の右辺値を渡すことを禁止できます。
これは、組み込みスカラーに対しても機能します。たとえば、double const f() { return 0.01; }
次のような警告が表示されます。
警告: 戻り型の 'const' 型修飾子は効果がありません [-Wignored-qualifiers]
コンストラクターのバージョン= delete;
のみの場合でも効果があります。&&
struct A
{
double const & eps;
A(double const & e) : eps(e) {} // binds to `double const &`, `double &` AND ! `double const &&`
A(double &&) = delete; // prohibit to binding only to `double &&`, but not to `double const &&`
};
double const get_eps() { return 0.01; }
A a{0.01}; // hard error
A a{get_eps()}; // no hard error, but it is wrong!
非変換コンストラクター (つまり、非単項) の場合、問題があり= delete;
ます。次のように、コンストラクターの組み合わせで可能なすべてのバージョンに対して -d バージョンを提供する必要がある場合があります。
struct A
{
A(B const &, C const &) {}
A(B const &&, C const &&) = delete;
// and also!
A(B const &, C const &&) = delete;
A(B const &&, C const &) = delete;
};
次のような大文字と小文字の混合を禁止します。
B b{};
A a{b, C{}};