template<class Y>
operator auto_ptr_ref<Y>() throw() {
return auto_ptr_ref<Y>(release());
}
これは、標準ライブラリのクラス auto_ptr の実装の一部です。
これは何をすることを意味しますか?
「演算子」と「()」の間に「auto_ptr_ref」があるのはなぜですか?
template<class Y>
operator auto_ptr_ref<Y>() throw() {
return auto_ptr_ref<Y>(release());
}
これは、標準ライブラリのクラス auto_ptr の実装の一部です。
これは何をすることを意味しますか?
「演算子」と「()」の間に「auto_ptr_ref」があるのはなぜですか?
その変換演算子がたまたまそこにある理由を説明します。さて、この例を見てください:
struct A;
struct B {
explicit B(A&a):a(a){ }
A &a;
};
struct A {
A() { }
A(B b){ move_from(a); }
A(A &a) { move_from(a); }
operator B() { return B(*this); }
void move_from(A &a) {
std::cout << "A::A(@" << &b.a << ")" << std::endl;
}
};
int main() {
A a = A();
}
クラス A のムーブ セマンティクスがあります。そのコピー コンストラクターでは、他のインスタンスからいくつかのものを「盗む」必要があります。auto_ptr の場合、これは管理対象のポインターであり、代わりにメッセージを出力するだけです。重要なのは、通常のコピー コンストラクターを使用できないことです。
A(A const& a) {
/* oops, a is const, we can't steal something from it! */
}
しかし、それを に変更するとA(A &a)
、値渡し/一時的な A から構築できなくなります。これらは非定数への参照にバインドできません。
A(A &a) {
}
...
A a = A(); // fail, because A &a = A() doesn't work
auto_ptr と私たちの A クラスは、一時的/値渡しの A で非 const メンバー関数を引き続き呼び出すことができるというトリックを使用します。つまり、次のように書くこともできます。
struct A {
...
B get_b() { return B(*this); }
...
};
...
A a = A().get_b();
しかし、それは機能します。もちろん、私たちはそれに悩まされたくありません. A()
値渡しを返す関数の戻り値または戻り値を代入するだけで機能することを望みA
ます。したがって、auto_ptr と A クラスが使用するのは変換演算子です。これは、A が B に変換されると、一時的に作成した B を使用して A インスタンスを構築できることを自動的に判断します。
これは、auto_ptr から auto_ptr_ref<Y> にキャストする変換演算子の動作です。