8

Possible Duplicate:
What’s the motivation behind having copy and direct initialization behave differently?

And by copy initialization, I mean like so:

struct MyStruct
{
    MyStruct(int) {}
    MyStruct(const MyStruct&) {}
};

MyStruct s = 5; // needs *both* the int and copy constructor

Despite programming in C++ for years, I never realized the above code required the copy constructor (thanks to jogojapan). The temporary had always been elided, and as such I never even knew it even existed (at least on a superficial level, despite it being optimized away) until it was pointed out to me.

After a decent amount of googling, I get the idea of how it works. My question is why is it the way it is?

Why didn't the standard make it so that the above example doesn't need the copy constructor? Is there some specific case/example that shows that requiring the copy constructor in this type of initialization is important?

Without a decent explanation of why things are they way they are, I just see this as an annoying artifact, but I'd rather not be ignorant if there's something important that I'm missing.

Community
  • 1
  • 1
Cornstalks
  • 37,137
  • 18
  • 79
  • 144
  • It seems that need of copy constructor is for namesake; actually it's [not called](http://ideone.com/35fjAD). – iammilind Dec 04 '12 at 04:27
  • @iammilind: It need not be called is due to **Copy elision**, but the copy constructor needs to be accessible.Basically, it means that the standard *allows* copy constructor to be called and it **must** be available. The Optimization is not standardese guaranteed infact its the contrary that standard accomodates for. – Alok Save Dec 04 '12 at 04:29
  • 1
    @JesseGood: Thanks for that. Looks like this is pretty much a duplicate. Kind of depressing there isn't a good answer on that other question... – Cornstalks Dec 04 '12 at 04:29
  • @Cornstalks: Actually, I think the most-upvoted answer is right: `It was designed this way because it was assumed such behaviour will be expected by the programmer` IIRC, the only reason we have `MyStruct s = 5;` syntax (using =) is because so many people are used to it. – Jesse Good Dec 04 '12 at 04:34
  • 1
    @JesseGood: I suppose that makes sense. I think that explanation paired with the earlier explanation that `MyStruct s = 5;` is more or less converted to `MyStruct s = MyStruct(5);` in order to convert the `5` to a `MyStruct` makes sense as a reasonable explanation. – Cornstalks Dec 04 '12 at 04:39

1 Answers1

0

Copy initialization of an object is ambiguous to direct initialization, both can be used to the same extent in order to set values equal to each other.

int a = 4;
int a = int(4);
int a(4);

all of these calls are ambiguous, they all set a equal to 4. The reason for a copy constructor in the case of an integer is convenience, imagine c++ data types without this

int a(foo(b,r)); //a little messy for a variable declaration
int a = foo(b,r) //ok, cleaner

you also might might to use an implicit and explicit copy constructor, here is an example program that uses a copy constructor explicitly to handle imaginary numbers:

#include <iostream>
using std::cout;
using std::endl;
class complexNumbers {
  double real, img;
public:
  complexNumbers() : real(0), img(0) { }
  complexNumbers(const complexNumbers& c) { real = c.real; img = c.img; }
  explicit complexNumbers( double r, double i = 0.0) { real = r; img = i; }
  friend void display(complexNumbers cx);
};
void display(complexNumbers cx){
  cout<<&quot;Real Part: &quot;<<cx.real<<&quot; Imag Part: &quot;<<cx.img<<endl;
}
int main() {
  complexNumbers one(1);
  display(one);
  complexNumbers two =2;
  display(200);
  return 0;
}
Syntactic Fructose
  • 18,936
  • 23
  • 91
  • 177