I know that at least one of the changes in C++11 that will cause some old code to stop compiling: the introduction of explicit operator bool()
in the standard l
Some core incompatibilities that are not covered by the incompatibilities section:
C++0x treats the injected class name as a template, if the name is passed as an argument to a template template parameter, and as a type if it is passed to a template type parameter.
Valid C++03 code may behave differently if it relies on the injected class name to be always a type in these scenarios. Example code taken from my clang PR
template class X>
struct M { };
template class X>
void g(int = 0); // #1
template
void g(long = 0); // #2
template
struct A {
void f() {
g(); /* is ambiguous in C++0x */
g(1); /* should choose #1 in C++0x */
}
};
void h() {
A a;
a.f();
}
In C++03, the code calls the second g
both times.
C++0x makes some names that were dependent in C++03 to be now non-dependent. And requires name lookup for non-dependent qualified names that refer to members of the current class template to be repeated at instantiation, and requires verification that these names lookup the same way as done at the template definition context.
Valid C++03 code that depends on the dominance rule may now not compile anymore because of this change.
Example:
struct B { void f(); };
template
struct A : virtual B { void f(); };
template
struct C : virtual B, A {
void g() { this->f(); }
};
int main() { C c; c.g(); }
This valid C++03 code that calls A
is not valid in C++0x, because name lookup when instantiating will find A
as opposed to B::f
, causing a conflict with the at-definition lookup.
At this point, it is not clear whether that is a defect in the FDIS. The committee is aware of this and will evaluate the situation.
A using declaration where the last part is the same as the identifier in the last part of the qualifier in the qualified name denoting a base class, that using declaration now names the constructor, instead of members with that name.
Example:
struct A { protected: int B; };
typedef A B;
struct C : B {
// inheriting constructor, instead of bringing A::B into scope
using B::B;
};
int main() { C c; c.B = 0; }
The above example code is well-formed in C++03, but ill-formed in C++0x, as A::B
is still inaccessible in main
.