468,791 Members | 1,794 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,791 developers. It's quick & easy.

Explicit copy constructor

Hi,

gcc 3.4 rejects the following program:

class T {
public:
T() : a(3) {}
explicit T(T const & other) : a(other.a) {}
private:
int a;
};

void func(T const & obj) {
}

int main() {
func(T());
}

The error is:

no matching function for call to `T::T(const T&)'

There is some reasoning about it at:

http://gcc.gnu.org/bugs.html#cxx_rvalbind

This seems to be correct for private copy constructors, but I am not sure
whether the interpretation by the gcc team also applies to explicit copy
constructors. Is there some discussion about the correct interpretation of
the standard for explicit copy constructors?

Christoph Bartoschek
Jul 22 '05 #1
6 6939
"Christoph Bartoschek" <ba********@gmx.de> wrote...
Hi,

gcc 3.4 rejects the following program:

class T {
public:
T() : a(3) {}
explicit T(T const & other) : a(other.a) {}
private:
int a;
};

void func(T const & obj) {
}

int main() {
func(T());
}

The error is:

no matching function for call to `T::T(const T&)'

There is some reasoning about it at:

http://gcc.gnu.org/bugs.html#cxx_rvalbind

This seems to be correct for private copy constructors, but I am not sure
whether the interpretation by the gcc team also applies to explicit copy
constructors. Is there some discussion about the correct interpretation of
the standard for explicit copy constructors?


Explicit constructor requires the direct initialiser syntax or
an explicit cast. Creation of a temporary from an r-value for
binding a temporary (even if it's not done that way) is all
implicit. It seems that if copy-constructor is declared explicit
would prevent a temporary object from initialising (since no
syntax can be used for that).

Why would you want to have the copy c-tor explicit?

Victor
Jul 22 '05 #2
Christoph Bartoschek <ba********@gmx.de> wrote in message news:<vs************@ID-80222.user.uni-berlin.de>...
Hi,

gcc 3.4 rejects the following program:

class T {
public:
T() : a(3) {}
explicit T(T const & other) : a(other.a) {}
private:
int a;
};

void func(T const & obj) {
}

int main() {
func(T());
}

The error is:

no matching function for call to `T::T(const T&)'

There is some reasoning about it at:

http://gcc.gnu.org/bugs.html#cxx_rvalbind

This seems to be correct for private copy constructors, but I am not sure
whether the interpretation by the gcc team also applies to explicit copy
constructors. Is there some discussion about the correct interpretation of
the standard for explicit copy constructors?

Christoph Bartoschek


The whole point of declaring a constructor explicit is that it can
only be called *explicitly*:

T apple;
T orange(apple);

Your code is generating an *implicit* copy constructor call, thus the
behavior makes sense using the logic laid out in the gcc document.
Specifically, the proper semantics for the copy constructor call are
not being obeyed in your case since the copy constructor is being
called implicitly.

HTH, Dave Moore

P.S. Why do you want an explicit copy constructor?
Jul 22 '05 #3
>class T {
public:
T() : a(3) {}
explicit T(T const & other) : a(other.a) {}
private:
int a;
};

void func(T const & obj) {
}

int main() {
func(T());
}


I don't understand how the error is being generated.

Where is a copy-constructor being called implicitly in this code?

What am I missing?

I can tell you that this code compiled at www.comeaucomputing.com using their
online compiler.
Jul 22 '05 #4
Christoph Bartoschek <ba********@gmx.de> wrote in message news:<vs************@ID-80222.user.uni-berlin.de>...
Hi,

gcc 3.4 rejects the following program:

class T {
public:
T() : a(3) {}
explicit T(T const & other) : a(other.a) {}
private:
int a;
};

void func(T const & obj) {
}

int main() {
func(T());
}

The error is:

no matching function for call to `T::T(const T&)'

There is some reasoning about it at:

http://gcc.gnu.org/bugs.html#cxx_rvalbind

This seems to be correct for private copy constructors, but I am not sure
whether the interpretation by the gcc team also applies to explicit copy
constructors. Is there some discussion about the correct interpretation of
the standard for explicit copy constructors?


Yes, CWG issue 152. It changed between C++98 and C++03.

The new rules are:

When objects of class type are direct-initialized (8.5 dcl.init), or
copy-initialized from an expression of the same or a derived class
type (8.5 dcl.init), overload resolution selects the constructor. For
direct-initialization, the candidate functions are all the
constructors of the class of the object being initialized. For
copy-initialization, the candidate functions are all the converting
constructors (12.3.1 class.conv.ctor ) of that class.

A non-explicit copy constructor (12.8 class.copy) is a converting
constructor.

This form requires copy-initialization to copy the temporary to the
bound argument (although the actual copy may be optimized out). In
this case, there's no converting ctor available.

Regards,
Michiel Salters
Jul 22 '05 #5
Victor Bazarov wrote:

....
Why would you want to have the copy c-tor explicit?


This was not my decision. But:

We have a a class Node which is can be copied and used as a POD. However the
addresses of objects of Node are used as indexes for the interface of the
underlying C subsystem. 95% of all uses of Node are in conjunction with
this subsystem. Most mistakes when using this system came from constructs
like this:

Node node = bla.get_node();
subsystem_get_parent(handle(node));

It is hard to find such an error. Therefore it was decided, that the copy
constructor of Node becomes explicit to avoid such mistakes. Now each time
one forgets the reference character the compiler complains.

Christoph Bartoschek
Jul 22 '05 #6
Michiel Salters wrote:
....
Yes, CWG issue 152. It changed between C++98 and C++03.

The new rules are:

When objects of class type are direct-initialized (8.5 dcl.init), or
copy-initialized from an expression of the same or a derived class
type (8.5 dcl.init), overload resolution selects the constructor. For
direct-initialization, the candidate functions are all the
constructors of the class of the object being initialized. For
copy-initialization, the candidate functions are all the converting
constructors (12.3.1 class.conv.ctor ) of that class.

A non-explicit copy constructor (12.8 class.copy) is a converting
constructor.

This form requires copy-initialization to copy the temporary to the
bound argument (although the actual copy may be optimized out). In
this case, there's no converting ctor available.


Thanks, this argumentation was convincing.

Christoph Bartoschek
Jul 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Jean Stax | last post: by
12 posts views Thread by Marcelo Pinto | last post: by
8 posts views Thread by trying_to_learn | last post: by
2 posts views Thread by Dave | last post: by
2 posts views Thread by Fred Zwarts | last post: by
1 post views Thread by =?gb2312?B?wfXquw==?= | last post: by
12 posts views Thread by Rahul | last post: by
reply views Thread by zhoujie | last post: by
2 posts views Thread by Marin | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.