473,396 Members | 1,774 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Overload resolution and copy constructors that take non-const references

Hi,

Should the following compile, and what should it print?

#include <memory>
#include <iostream>

void foo(std::auto_ptr<intx)
{
std::cout<<"copy"<<std::endl;
}

struct dummy
{
dummy(std::auto_ptr<intconst&)
{}
};

void foo(dummy x)
{
std::cout<<"dummy const ref"<<std::endl;
}

int main()
{
std::auto_ptr<intconst x(new int);
foo(x);
}

MSVC 9.0 and g++ 4.3 disagree.

MSVC compiles it and prints "dummy const ref", which is what I expected.

g++ refuses to compile it, saying that:

test_copy.cpp: In function 'int main()':
test_copy.cpp:23: error: passing 'const std::auto_ptr<int>' as 'this' argument o
f 'std::auto_ptr<_Tp>::operator std::auto_ptr_ref<_Tp1>() [with _Tp1 = int, _Tp
= int]' discards qualifiers
test_copy.cpp:23: error: initializing argument 1 of 'void foo(std::auto_ptr<in
t>)'

implying that it chose the first overload of foo.

Anthony
--
Anthony Williams | Just Software Solutions Ltd
Custom Software Development | http://www.justsoftwaresolutions.co.uk
Registered in England, Company Number 5478976.
Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL
Jun 27 '08 #1
9 2290
On May 7, 11:44*am, Anthony Williams <anthony_w....@yahoo.comwrote:
Hi,

Should the following compile, and what should it print?
Really, I don't know.Sorry to answer question
with question.
>
#include <memory>
#include <iostream>

void foo(std::auto_ptr<intx)
Is same as
void foo(const std::auto_ptr<intx) ?
struct dummy
{
* * dummy(std::auto_ptr<intconst&)
* * {}

};

void foo(dummy x)
....
int main()
{
* * std::auto_ptr<intconst x(new int);
* * foo(x);

}

MSVC 9.0 and g++ 4.3 disagree.

MSVC compiles it and prints "dummy const ref", which is what I expected.

g++ refuses to compile it, saying that:
....
It isn;t clear to me following example:

class A{
public:
A(){}
A(A&){}
};

A foo(){ return A(); }

int main()
{
A a;
a = foo();
}

g++ gives strange error:

cctor.cpp: In function ‘A foo()’:
cctor.cpp:7: error: no matching function for call to ‘A::A(A)’
cctor.cpp:4: note: candidates are: A::A(A&)
cctor.cpp: In function ‘int main()’:
cctor.cpp:12: error: no matching function for call to ‘A::A(A)’
cctor.cpp:4: note: candidates are: A::A(A&)

I don;t have msvc handy but I think saw somewhere,
that, it compiles without error.
So, perhaps, as g++ wants A(A) this is similar to
your question.
As I never used non const reference copy constructor,
I'm really confused about it's behavior.
It seems to me that compiler writers are too ;)

Greetings, Branimir.
Jun 27 '08 #2
Branimir Maksimovic wrote:
....
It isn;t clear to me following example:

class A{
public:
A(){}
A(A&){}
};

A foo(){ return A(); }

int main()
{
A a;
a = foo();
}

g++ gives strange error:

cctor.cpp: In function ‘A foo()’:
cctor.cpp:7: error: no matching function for call to ‘A::A(A)’
cctor.cpp:4: note: candidates are: A::A(A&)
cctor.cpp: In function ‘int main()’:
cctor.cpp:12: error: no matching function for call to ‘A::A(A)’
cctor.cpp:4: note: candidates are: A::A(A&)
Returning a temporary from 'foo' requires copy-constructing
another temporary (allowed to be optimized away, but semantially
should still be possible). But the only copy c-tor in 'A' takes
a ref to non-const A. The ref argument for 'A(A&)' cannot be
bound to the temporary, and that would probably be a clearer
message...
>
I don;t have msvc handy but I think saw somewhere,
that, it compiles without error.
... unless you disable language extensions ..
So, perhaps, as g++ wants A(A) this is similar to
your question.
As I never used non const reference copy constructor,
I'm really confused about it's behavior.
It seems to me that compiler writers are too ;)
I don't believe that's the case (about the writers).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #3
On May 7, 2:59*pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Branimir Maksimovic wrote:
....
It isn;t clear to me following example:
class A{
public:
* A(){}
* A(A&){}
};
A foo(){ return A(); }
int main()
{
* A a;
* a = foo();
}
g++ gives strange error:
cctor.cpp: In function ‘A foo()’:
cctor.cpp:7: error: no matching function for call to ‘A::A(A)’
cctor.cpp:4: note: candidates are: A::A(A&)
cctor.cpp: In function ‘int main()’:
cctor.cpp:12: error: no matching function for call to ‘A::A(A)’
cctor.cpp:4: note: candidates are: A::A(A&)

Returning a temporary from 'foo' requires copy-constructing
another temporary (allowed to be optimized away, but semantially
should still be possible). *But the only copy c-tor in 'A' takes
a ref to non-const A. *The ref argument for 'A(A&)' cannot be
bound to the temporary, and that would probably be a clearer
message...
I don;t think that's the case since g++ gives proper
error if, for example, ordinary function foo takes non const reference
to temporary.In this case g++ really wants A(A),
I think. But then again, you may be right, it's just
strange error.

What about
A foo()
{
A a;
return a;
}
A a;
a = foo();
Is compiler obliged to call copy constructor?
>

I don;t have msvc handy but I think saw somewhere,
that, it compiles without error.

.. unless you disable language extensions ..
I think that msvc issues warning if that's the case.
But I am really not sure, could be what you say,
so someone with msvc with disabled extensions
could confirm that this does not compile (second version
of foo that does not returns temporary perhaps).

Greetings, Branimir.
Jun 27 '08 #4
On May 7, 3:21*pm, Branimir Maksimovic <bm...@hotmail.comwrote:
What about
A foo()
{
* A a;
* return a;}

A a;
a = foo();
Is compiler obliged to call copy constructor?
Err, I mean to construct temporary.
It will call copy constructor all right, but
still gives error that it wants A(A)

Greetings, Branimir.
Jun 27 '08 #5
Branimir Maksimovic wrote:
On May 7, 3:21 pm, Branimir Maksimovic <bm...@hotmail.comwrote:
>What about
A foo()
{
A a;
return a;}

A a;
a = foo();
Is compiler obliged to call copy constructor?

Err, I mean to construct temporary.
Yes, with assignment it would have to create a temporary (and BTW
I really hope the 'a = foo();' statement is inside some function
otherwise it would be ill-formed). There are no provisions in the
Standard to allow skipping creating a temporary when one would be
required because the expression on the right-hand side of the
assignment operator produces it. The creation of the temporary
is only allowed to be skipped in the case of initialising an object
of the same type:

A a = foo();
It will call copy constructor all right, but
still gives error that it wants A(A)
Sorry, I don't know what you mean here.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #6
Victor Bazarov wrote:
Branimir Maksimovic wrote:
>On May 7, 3:21 pm, Branimir Maksimovic <bm...@hotmail.comwrote:
>>What about
A foo()
{
A a;
return a;}

A a;
a = foo();
Is compiler obliged to call copy constructor?

Err, I mean to construct temporary.

Yes, with assignment it would have to create a temporary (and BTW
I really hope the 'a = foo();' statement is inside some function
otherwise it would be ill-formed). There are no provisions in the
Standard to allow skipping creating a temporary when one would be
required because the expression on the right-hand side of the
assignment operator produces it. The creation of the temporary
is only allowed to be skipped in the case of initialising an object
of the same type:

A a = foo();
I think there was one more case where copy ctor elusion is permited. I would
also like to add that this is special treatement in the standard for these
cases even if the copy ctor has observable behaviour altering code. Because
in general if calling or not calling the copy ctor results in the same
observable behaviour (which is to be expected to most copy ctors that
usually don't have side effects) then the compiler can optimize out the
call anyway no matter of being in such a special case or not :)

--
Dizzy

Jun 27 '08 #7
dizzy wrote:
Victor Bazarov wrote:
>Branimir Maksimovic wrote:
>>On May 7, 3:21 pm, Branimir Maksimovic <bm...@hotmail.comwrote:
What about
A foo()
{
A a;
return a;}

A a;
a = foo();
Is compiler obliged to call copy constructor?

Err, I mean to construct temporary.

Yes, with assignment it would have to create a temporary (and BTW
I really hope the 'a = foo();' statement is inside some function
otherwise it would be ill-formed). There are no provisions in the
Standard to allow skipping creating a temporary when one would be
required because the expression on the right-hand side of the
assignment operator produces it. The creation of the temporary
is only allowed to be skipped in the case of initialising an object
of the same type:

A a = foo();

I think there was one more case where copy ctor elusion is permited.
Binding of a reference to const does not have to create a temporary
(although it could), if the referred type is the same or the derived
class as the temporary, IIRC. The requirement is, however, that the
copy c-tor shall [still] be available _as if_ the copy is made.
I would also like to add that this is special treatement in the
standard for these cases even if the copy ctor has observable
behaviour altering code. Because in general if calling or not calling
the copy ctor results in the same observable behaviour (which is to
be expected to most copy ctors that usually don't have side effects)
then the compiler can optimize out the call anyway no matter of being
in such a special case or not :)
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #8
On May 7, 4:25*pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Branimir Maksimovic wrote:
It will call copy constructor all right, but
still gives error that it wants A(A)

Sorry, I don't know what you mean here.
I had to wait several hours to be sure that this is
not already sent, because I clicked send twice
but google didn't confirmed.
Ok, following program does not compiles:

class A{
public:
A(){}
A(A&){}
};

A foo()
{
A a;
return a;
}

int main()
{
A a;
a = foo();
}

bmaxa@maxa:~$ g++ -Wall cctor.cpp -o cctor
cctor.cpp: In function ‘int main()’:
cctor.cpp:16: error: no matching function for call to ‘A::A(A)’
cctor.cpp:4: note: candidates are: A::A(A&)

Since temporary is constructed by local variable now, I think
that this should compile since A::A(A&) should be called.
But I got same error again.
That is what confuses me. Is compiler right or should
this compile?
Thanks for your time (I'm really rusty with English language)

Greetings, Branimir.
Jun 27 '08 #9
On May 7, 11:44 am, Anthony Williams <anthony_w....@yahoo.comwrote:
Should the following compile, and what should it print?
I'm not sure, but it's a very delicate point, and it wouldn't
surprise me if a lot of compilers get it wrong.
#include <memory>
#include <iostream>
void foo(std::auto_ptr<intx)
{
std::cout<<"copy"<<std::endl;

}
struct dummy
{
dummy(std::auto_ptr<intconst&)
{}
};
void foo(dummy x)
{
std::cout<<"dummy const ref"<<std::endl;
}
int main()
{
std::auto_ptr<intconst x(new int);
foo(x);
}
MSVC 9.0 and g++ 4.3 disagree.
MSVC compiles it and prints "dummy const ref", which is what I expected.
g++ refuses to compile it, saying that:
test_copy.cpp: In function 'int main()':
test_copy.cpp:23: error: passing 'const std::auto_ptr<int>' as 'this' argument o
f 'std::auto_ptr<_Tp>::operator std::auto_ptr_ref<_Tp1>() [with _Tp1 = int, _Tp
= int]' discards qualifiers
test_copy.cpp:23: error: initializing argument 1 of 'void foo(std::auto_ptr<in
t>)'
implying that it chose the first overload of foo.
Both functions are found during lookup, and are part of the
initial set of candidate functions. The question is whether the
first is viable. It meets the first condition (it can be called
with a single argument). The exact wording it:

Second, for F to be a viable function, there shall exist
for each argument an implicit conversion sequence
(13.3.3.1) that converts that argument to the
corresponding parameter of F. If the parameter has
reference type, the implicit conversion sequence
includes the operation of binding the reference, and the
fact that a reference to non-const cannot be bound to an
rvalue can affect the viability of the function (see
13.3.3.1.4).

The question hinges on whether there is "an implicit conversion
sequence" which converts an std::auto_ptr<intconst to an
std::auto_ptr<int>. And I think that the standard is far from
clear about this. In particular, §13.3.3.1 says:

When the parameter type is not a reference, the implicit
conversion sequence models a copy-initialization of the
parameter from the argument expression. The implicit
conversion sequence is the one required to convert the
argument expression to an rvalue of the type of the
parameter. [Note: when the parameter has a class type,
this is a conceptual conversion defined for the purposes
of clause 13; the actual initialization is defined in
terms of constructors and is not a conversion. ] Any
difference in top-level cv-qualification is subsumed by
the initialization itself and does not constitute a
conversion. [Example: a parameter of type A can be
initialized from an argument of type const A. The
implicit conversion sequence for that case is the
identity sequence; it contains no ¿conversion¿ from
const A to A.] When the parameter has a class type and
the argument expression has the same type, the implicit
conversion sequence is an identity conversion. When the
parameter has a class type and the argument expression
has a derived class type, the implicit conversion
sequence is a derived-to-base Conversion from the
derived class to the base class. [Note: there is no
such standard conversion; this derived-to-base
Conversion exists only in the description of implicit
conversion sequences.] A derived-to-base Conversion has
Conversion rank (13.3.3.1.1).

Note that there is actually a contradiction in this text for the
case which interests us: "the implicit conversion sequence
models a copy-initialization of the parameter from the argument
expression", which bans the initialization of an std::auto_ptr<>
from an std::auto_ptr<const, and "Any difference in top-level
cv-qualification is subsumed by the initialization itself and
does not constitute a conversion", which explicitly says that
the case in question does *not* constitute a conversion, i.e.
that it is treated as an exact match.

Of course, once the first function has crossed the line and is
considered viable, it's obviously the "best viable function"; if
it is to be eliminated, it can only be because it isn't viable.
Globally, I think that the intent is probably that the function
shouldn't be viable, since the argument cannot be used to
initialize a variable of the type of the argument. But the
wording in the paragraph I just cited seems contradictory enough
that it can be interpreted either way.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

42
by: Edward Diener | last post by:
Coming from the C++ world I can not understand the reason why copy constructors are not used in the .NET framework. A copy constructor creates an object from a copy of another object of the same...
8
by: Jesper | last post by:
Hi, Does the concept "copy constructor" from c++ excist in c#. What is the syntax. best regards Jesper.
10
by: Benny Raymond | last post by:
I'm trying to change the way a treeview works just a bit, i'm pretty new to C# and now i'm running into overloading. I tried the following code and it's yelling at me saying that no overload...
13
by: Vladimir Granitsky | last post by:
Hi guys, Please, look at the code below and try to step into it. The compiled code calls the loosely typed method public void Method1(object o) !?!? Am I right that C# compiler does wrong...
0
by: Eph0nk | last post by:
Hi, I get an overload resolution failed error (Overload resolution failed because no accessible 'New' can be called without a narrowing conversion), and I can't seem to find a lot of relevant...
1
by: steve | last post by:
I am trying to create an XSLT Transform but keep getting the same problem. Overload resolution failed because no accessible 'Transform' can be called with these arguments. I create a reference...
5
by: Jess | last post by:
Hi, I understand that if I define a constructor, then the compiler won't synthesize any constructor for me. How about copy constructor and assignment operator? WIll compiler stop synthesizing...
5
by: jknupp | last post by:
In the following program, if the call to bar does not specify the type as <int>, gcc gives the error "no matching function for call to ‘bar(A&, <unresolved overloaded function type>)’". Since bar...
2
by: zbigniew | last post by:
Can someone explain me how overload resolution works in C++? For example if I have function void f(char, int); and I will call f('A', 3.1) or f(1.5, 3.1F) what would be the result? Thanks
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.