Re: c++98/c++03 constructor overloading
On Tue, 07 Dec 2010 13:31 +0100
"Johannes Schaub (litb)" <schaub-johannes@web.de> wrote:
Chris Vine wrote:
Hi,
With gcc-4.2 and earlier, and with subsequent versions of gcc when
using the -std=c++98 option, the following code fails to compile:
--------------------------
#include <iostream>
#include <ostream>
enum ByRef {by_ref};
template <class T>
class MyClass {
T t;
public:
MyClass(const T& arg): t(arg) { // (1)
std::cout << "Without ByRef tag" << std::endl;
}
MyClass(T arg, ByRef): t(arg) { // (2)
std::cout << "With ByRef tag" << std::endl;
}
};
int main() {
int i = 0;
MyClass<int&> m2(i, by_ref);
}
--------------------------
gcc ignores the ByRef tag, and picks constructor 1, and then fails
to compile because of the resulting reference to a reference.
No, It's an error right way when you implicitly instantiate
MyClass<int&>. Try
sizeof(MyClass<int&>);
On a literal C++03 compiler, this *must* result in a compile error
because the declaration of the destructor is invalid. You don't even
get to the point where a constructor could be chosen by overload
resolution.
If I omit constructor (1), the code compiles, as does
sizeof(MyClass<int&>).
However, I think I can now see the problem: the constructor is not
templated (it can't be), so SFINAE does not apply. This means
constructor (1) must be capable of compiling for an instantiation of
MyClass<int&> even if it is never in fact called.
So gcc and comeau must, for the purposes of overload resolution, be
accepting a reference to a reference. I assume then that Comeau in
strict c++03 mode is still accepting some non-c++03 constructs?
Chris