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.
Without the -std=c++98 option, gcc-4.3 onwards pick the right overload
(constructor 2), as does Comeau in strict c++03 mode.
Is this a gcc bug or do c++98 overload rules compel the tag
enumeration to be ignored and the incorrect constructor to be called?
If c++98 overload rules compel this behaviour, at what point did it
change (is it a c++03 thing, or in anticipation of c++0x?)
Chris
|
|
0
|
|
|
|
Reply
|
Chris
|
12/7/2010 12:00:02 PM |
|
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.
> Without the -std=c++98 option, gcc-4.3 onwards pick the right overload
> (constructor 2), as does Comeau in strict c++03 mode.
>
More recent compilers implement this according to various C++ DR
resolutions.
|
|
0
|
|
|
|
Reply
|
Johannes
|
12/7/2010 12:31:00 PM
|
|
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
|
|
0
|
|
|
|
Reply
|
Chris
|
12/7/2010 12:41:15 PM
|
|
On Tue, 7 Dec 2010 12:41:15 +0000
Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
[snip]
> > 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.
> > >
[snip]
> 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?
If reference to reference template arguments are not acceptable in
c++03, I think I am going to have to resort to partial template
specialisation for my purposes, which appears to behave correctly:
template <class T>
class MyClass {
T t;
public:
MyClass(const T& arg): t(arg) {std::cout << "Not ref type" <<
std::endl;} };
template <class T>
class MyClass<T&> {
T t;
public:
MyClass(T arg): t(arg) {std::cout << "Ref type" << std::endl;}
};
This is fairly grotesque. Is anyone more knowledgeable than me able to
confirm whether strict c++03 (as well as c++98) does reject template
instantiations giving a reference to a reference, so requiring this
work around? (Sometimes I really detest c++.)
Chris
|
|
0
|
|
|
|
Reply
|
Chris
|
12/7/2010 1:16:49 PM
|
|
|
3 Replies
133 Views
(page loaded in 0.074 seconds)
Similiar Articles: Const constructor - comp.lang.c++.moderatedDragan: 6/16/2009 7:47:03 AM ... private: T* ptr; }; A C++98 ... The 'const char *' constructor. 4. operator<< overload for ostream. std::map< MyString, MyString > comparison operator? - comp.lang ...The 'const char *' constructor. 4. operator<< overload for ostream. Copy and assignment were left ... 4/13/2005 8:03:58 PM glut and (Visual)C++ - comp.graphics.api.openglHello, I've got a C program where display, reshape ... OnReshape(iWidth,iHeight); } Notice that the constructor ... free opengl code using visual c++ 98 - comp.graphics ... glut fatal error - comp.graphics.api.opengl... C++ object that is declared in a source file, its constructor ... Reply: junkqwe1: 12/24/2003 9:03:39 PM ... free opengl code using visual c++ 98 - comp.graphics ... enum and operator++ - comp.lang.c++Incrementing an enum variable? - comp.lang.c Enum ... In C++, there is an overload of operator<< to output char ... Const constructor - comp.lang.c++.moderated What would copy ... When would you declare a method as static? - comp.lang.java.help ...On 03/27/2011 05:23 PM, Merciadri Luca wrote: > I ... http://upload.wikimedia.org/wikipedia/commons/c/cf ... generalized class , doubling as its own constructor and ... Adding simple database, excel export, and reports with D4 Pro ...... have been an enumeration (and in the 64-bit overload, it ... Index : integer) : TDataItem; public constructor ... Reply: Paul: 11/1/2009 11:43:03 AM Some text processing questions - comp.lang.vhdlc'mon, folks, where's the ability to overload assignment in ... On 1 Apr 2007 01:03:39 -0700, "Eli Bendersky" <eliben ... 16 Replies 98 Views (0.224 seconds) Tweet Use of MATLAB fftshift - comp.dsp... array arithmetic would also have to be modified (by overloading ... just like "complex" should be a basic type in C. it ... On 27 Jun, 22:03, robert bristow-johnson <r ... Reason 412: The remote peer is no longer responding. - comp.dcom ...... to see a summary of what is or is not happening: C ... inside source route-map SDM_RMAP_1 interface Dialer0 overload ... 80.177.223.54 access-list 101 permit udp host 82.0.98 ... overloading constructor in python?constructors: def __init__(self, c): if isinstance(c, int): ...do stuff... elif ... Re: c++98/c++03 constructor overloading: Johannes Schaub (litb) C++: 0: 12-07-2010 11:31 AM C++ - Wikipedia, the free encyclopedia... virtual functions, function name and operator overloading ... ISO/IEC 14882:1998 (informally known as C++98 For ... at its creation is known at compile time, constructors, and ... 7/18/2012 1:42:18 PM
|