hmm... I tested with the MinGW port of g++ 3.4.5, and the copy constructor was elided despite having side effects.But only if it is side-effect-free, I think. Otherwise, no compiler would ever create the temporary.
hmm... I tested with the MinGW port of g++ 3.4.5, and the copy constructor was elided despite having side effects.But only if it is side-effect-free, I think. Otherwise, no compiler would ever create the temporary.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
i can't make it private, it's a template. and private comes before public in my case so that's a problemo.
However i thought the purpose of private copy-constructors was to explicitly prevent copying of an object?
Ubuntu Desktop
GCC/G++
Geany (for quick projects)
Anjuta (for larger things)
Okay, here's what the Section 12.8 of the C++ Standard has to say about this:
When certain criteria are met, an implementation is allowed to omit the copy construction of a class object, even if the copy constructor and/or destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization.111) This elision of copy operations is permitted in the following circumstances (which may be combined to eliminate multiple copies):
- in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object with the same cv-unqualified type as the function return type, the copy operation can be omitted by constructing the automatic object directly into the function's return value
- when a temporary class object that has not been bound to a reference (12.2) would be copied to a class object with the same cv-unqualified type, the copy operation can be omitted by constructing the temporary object directly into the target of the omitted copy
111) Because only one object is destroyed instead of two, and one copy constructor is not executed, there is still one object destroyed
for each one constructed.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
>> i can't make it private, it's a template. and private comes before public in my case so that's a problemo.
What does this mean?
>> However i thought the purpose of private copy-constructors was to explicitly prevent copying of an object?
That is one of the purposes, but you would also have to make the assignment operator private as well.
Besides, that shouldn't matter for you, making it private only matters in the context of the discussion about the differences in the syntaxes.
>>What does this mean?
It means as I was designing my template class, the only way I could get it to work was putting private first, and then public. I think the reasoning was that my class (List) has a private Node.
But then again, I'm no expert on templates or anything C++ for that matter, tis' why I ask questions of you experts.
Ubuntu Desktop
GCC/G++
Geany (for quick projects)
Anjuta (for larger things)
The order of private, public and protected in a class makes no difference. You can have multiple sections of each as well, it does not matter. It's possible that you need to declare one thing before another, but you can add another private section later.
Besides, you can put the private copy functions anywhere you want.
Okay, back to the discussion...
I acutally get a compiler error, that the copy ctor is private within this context:
I didn't really understand what laserlight and CornedBee were talking about earlier in this post, but maybe they can make sense of that.Code:List<m_type> m_list4 = m_list3 = m_list2;
Oh duh. It's in the initialization again. I see now.
But this compiles fine:
Code:m_list2 = m_list1;
Last edited by dudeomanodude; 03-06-2008 at 01:10 PM.
Ubuntu Desktop
GCC/G++
Geany (for quick projects)
Anjuta (for larger things)
Why are you making the copy constructor private?
As I said, there's no need for that unless you want copying to throw an error. That was just a side discussion, not advice for your class.
Edit: whoa, that took me way too long to prepare ...
OK, so before we go much further speculating wildly, I went and looked it up. My reference is N2521, the most recent C++0x draft. The relevant clause is 8.5/15.
The form T a = b; is called copy initialization, the form T a(b) direct initialization. (Paragraphs 12 and 13.) The draft says:
This confirms what we've said so far. Regarding the copy elision, I go consult 12.2 and 12.8.If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered. The applicable constructors are enumerated (13.3.1.3), and the best one is chosen through overload resolution (13.3). The constructor so selected is called to initialize the object, with the initializer expression(s) as its argument(s). If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed.
Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in 13.3.1.4, and the best one is chosen through overload resolution (13.3). If the conversion cannot be done or is ambiguous, the initialization is ill-formed. The function selected is called with the initializer expression as its argument; if the function is a constructor, the call initializes a temporary of the cv-unqualified version of the destination type. The temporary is an rvalue. The result of the call (which is the temporary for the constructor case) is then used to direct-initialize, according to the rules above, the object that is the destination of the copy-initialization. In certain cases, an
implementation is permitted to eliminate the copying inherent in this direct-initialization by constructing the intermediate result directly into the object being initialized; see 12.2, 12.8.
12.2/3 puts down the general principle that side effects from constructors of temporaries are relevant:
12.8/15, finally, lists the exceptions, i.e. the circumstances under which a temporary may be elided. The one we care about is this:When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1, 12.8), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4).
when a temporary class object that has not been bound to a reference (12.2) would be copied to a class object with the same cv-unqualified type, the copy operation can be omitted by constructing the temporary object directly into the target of the omitted copy
So you were right on all counts, laserlight.
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law