C
Vermutlich haben hier beide Compiler recht; die Frage, ob das Ganze eindeutig ist, hängt davon ab, wie rvalues an Referenzen gebunden werden - mithin Abschnitt 8.5.3. Dieser Teil des Standards ist nicht so ganz klar, im Übrigen wird es hier auch Änderungen in C++0x geben.
Ein Cast wie hier ist direkte Initialisierung, mithin wird aus allen möglichen Konstruktoren (anders als ich oben gesagt habe) der beste Ausgewählt.
Wir haben hier einmal
Foo (const FooBar* src);
um diesen benutzen zu können, brauchen wir den Konvertierungsoperator
operator FooBar* (void) const;
hierbei stimmt der Typ noch nicht ganz, wir müssen eine Qualifikationskonvertierung anschließen von FooBar* nach const FooBar*
Für den Kandidaten
Foo(const Foo&)
benötigen wir ein Foo als Argument, das kann entweder als Folge eines Konstruktoraufrufes (aber da haben wir nur Foo(const FooBar*)+operator FooBar*() und das ist unzulässig) oder eines Konvertierungsoperators wie hier:
operator Foo() const
Die Schwierigkeit besteht darin, zu bestimmen, wie dann dieses rvalue an die Referenz des Copy-ctors gebunden wird. Müssen wir (sinngemäß - eigentlich geht es um ein zusätzliches temporary) das Foo erst in const Foo umqualifizieren (so wie sich VC++2005 verhält), dann wäre dieser Pfad nicht besser als der oben besprochene über Foo(const FooBar*) und das Ganze ist mehrdeutig. Folgen wir der Interpretation von Comeau (g++ dürfte hier auch einzuordnen sein), dann erfolgt hier keine Qualifizierung und die Sequenz ist folglich besser als die über FooBar*.