2

コンストラクターのように「見える」関数に代入できるのに、コンストラクターに代入できないのはなぜですか?

例:

struct Bar {
   Bar() : b_(false) {}
   Bar(bool b) : b_(b) {}
};

struct Foo {
   Foo(Bar const & bar) : bar_(bar) {}
   Foo operator=(Foo const & f) { return Foo(f.bar_); }
   const Bar & bar_;
}

Foo bool_to_foo(bool b) { return Foo(Bar(b)); }

Foo MakeFoo(Bar const & bar) { return Foo(bar); }

なぜこれが機能するのですか:

Bar bar;
MakeFoo(bar) = bool_to_foo(true);

これがうまくいかないときは?

Bar bar;
Foo(bar) = bool_to_foo(true);  // Error: 'bar': redefinition; different basic types

MakeFoo(.) と Foo(.) は同じ署名と同じ機能を持っています。

コンストラクターの特別な点は何ですか?

4

2 に答える 2

8

この行:

Foo(bar) = bool_to_foo(true);

あなたが思っていることをしません。で初期化された一時オブジェクトは宣言されませbar。実際にはbar、typeという名前のオブジェクトを宣言Fooし、値を使用して初期化しますbool_to_foo(true)

その意味で、それは完全に次のものと同等です。

Foo bar = bool_to_foo(true);

barスコープ内に名前が付けられたオブジェクトがすでにあるため、これは再定義です。


それでも自分がやろうとしていることをやりたい場合は、次のことを試してみてください。

Foo((0,bar)) = bool_to_foo(true);

しかし、それは醜くて紛らわしいので、これ以上説明しません。

于 2013-02-05T16:07:51.057 に答える
0

関数はオブジェクトを返し、それMakeFoo()を次に割り当てることができます (ただし、一時的な割り当てについてコンパイラの警告が表示されるのではないかと思います)。ただし、ご想像のとおり、C++ 標準はコンストラクターに特別な扱いを与えます。完全にはわかりませんが、この= bool_to_foo(true)部分は代入ではなく初期化として扱われているのではないかと思います。foo にはコピー コンストラクターがないため、これによりエラーが発生します。

Rob はまた、Foo(bar) 取引で頭に釘を打ちました。C++ の構文は時々奇妙になることがあります。

いずれにせよ、これらの形式はどちらも悪い習慣です。右辺値への代入はおそらくあなたが望むものではなく、そうであれば人々を混乱させる可能性が最も高いです.

于 2013-02-05T16:12:03.660 に答える