RAD Studio
|
The compiler now obeys the rules of 8.5.1 and 13.3.1 of the 2003 C++ ANSI Standard for initialization and conversion:
// In this example, dst is destination type and src is source type class A { }; class V { public: V() { }; V( const V & ) { } V( const A & ) { } };G g; V v; // direct initialization // ==> constructors are considered. V v9(g); // Both of these statements previously compiled but now get the error: // Error E2015: Ambiguity between 'V::V(const V &)' and 'V::V(const A &)' // casts // (V)g is treated as V tmp(g) which is direct initialization of 'tmp' // ==> constructors are considered. (V)g; static_cast<V> (g); // Both of these statements previously compiled but now get the error: // Error E2015: Ambiguity between 'V::V(const V &)' and 'V::V(const A &)' // copy initialization with dst=V src=G // ==> user-defined conversion sequences are considered. V v4 = g; V v5 = G(); // Both of these statements now compile but previously got the error: // Error E2015: Ambiguity between 'V::V(const A &)' and 'V::V(const V &)' // copy initialization with dst=V src=V // ==> converting constructors of V are considered. V v6 = (V)g; V v7 = V(g); // Both of these statements compiled previously but now get the error: // Error E2015: Ambiguity between 'V::V(const V &)' and 'V::V(const A &)'
The new C++Builder 2007 compiler often reports ambiguities for conversions that involve user-defined operators. An example is shown below:
class AnsiString { public: bool operator ==(const AnsiString& other); AnsiString(const wchar_t* src); }; class Variant { public: operator AnsiString() const;operator wchar_t*() const; bool operator ==(const AnsiString& rhs) const { return static_cast<AnsiString>(*this) == rhs;}
C++Builder users might notice that the above is a stripped down version of the VCL AnsiString and Variant classes. Previous versions of the compiler invoked the 'Variant' 'operator AnsiString() const' for 'static_cast<AnsiString>(*this)', while C++Builder 2007 uses 'conversion via constructor'. Since the Variant can be converted to multiple types for which there are AnsiString constructors, the compiler generates an ambiguity error.
To correct this ambiguity error, you must eliminate the cast as in:
bool operator ==(const AnsiString& rhs) const { return (*this) == rhs;}
You can also be explicit about the operator:
bool operator ==(const AnsiString& rhs) const { return this->operator AnsiString() == rhs; }
The issue described above with a user-defined conversion operator vs. conversion via constructor might be encountered in several constructs involving the VCL classes Variant, OleVariant, AnsiString, WideString, TDateTime, Currency, and so forth.
The following table lists constructs that now generate error messages and the updated syntax.
Previous Construct |
Updated Construct |
Notes |
AnsiString test(OleVariant v) { AnsiString ret = (AnsiString) v; return ret; } |
AnsiString test(OleVariant v) { AnsiString ret = /*(AnsiString)*/ v; return ret; } |
Do not cast RHS when relying on conversion operator in an assignment. |
WideString test(OleVariant v) { WideString w(v); return w; } |
WideString test(OleVariant v) { WideString w = v; return w; } |
Use Copy Initialization instead of the more direct constructor. |
The underlying compiler change for the errors described above is related to the way the compiler now handles initialization and conversion.
Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
|
What do you think about this topic? Send feedback!
|