0
 struct Alien {
    int id;
    char const* name;
    Alien() = default;
    Alien(int id, char const* name) : id{id}, name{name} {}
    Alien(int id): id{id} {}
 };

 struct Spaceship {
    Alien alien1;
    Spaceship() = default;
    Spaceship(Alien const& z) {}
    Spaceship(Spaceship const& other) = default;
    Spaceship(Spaceship&& other) = default;
};

int main()
{
   Spaceship s1(3433); // works
   Spaceship s2(2322, "Kronas"); // error
}

source>:55:14: error: no matching constructor for initialization of 'Spaceship'
   Spaceship s(2322, "Kronas");
             ^ ~~~~~~~~
<source>:45:5: note: candidate constructor not viable: requires single argument 'z', but 2 arguments were provided
    Spaceship(Alien const& z) { }
    ^
<source>:46:5: note: candidate constructor not viable: requires single argument 'other', but 2 arguments were provided
    Spaceship(Spaceship const& other) = default;
    ^
<source>:47:5: note: candidate constructor not viable: requires single argument 'other', but 2 arguments were provided
    Spaceship(Spaceship&& other) = default;
    ^
<source>:44:5: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
    Spaceship() = default;
    ^
1 error generated.
Execution build compiler returned: 1

The std says that in direct initialization an implicit conversion to one of the T argument's constructor is applicable. Why the second initialization with two arguments throws an error?

cigien
  • 57,834
  • 11
  • 73
  • 112
Vegeta
  • 461
  • 2
  • 6
  • Are you expecting a conversion from those two arguments to one `Alien`? – molbdnilo Feb 02 '21 at 15:42
  • @molbdnilo yep, I misread. If you wrap the two arguments in braces it will work: `Spaceship s2({2322, "Kronas"})`, but maybe an explicit constructor is better. – Mansoor Feb 02 '21 at 15:51

1 Answers1

0

None of Spaceship constructors accepts two arguments. That is why it throws an error when you give it two. There should be something like:

 Spaceship(int number, char const* name){
   alien1.id = number;
   alien1.name = name;
};
Ofiec
  • 5
  • 5
  • If you're going to go this route, use the member initializer: `Spaceship(int number, char const *name): alien1(number, name) { }`. – 1201ProgramAlarm Feb 02 '21 at 15:56
  • Yeah, I didn't see that constructor. – Ofiec Feb 02 '21 at 16:01
  • Sorry for the late reply. The first one works bcoz, from the argument to T's implicit conversion is valid as per the std. But the second one fails don't know why? – Vegeta Feb 03 '21 at 02:23
  • 1
    @Vegeta It fails because `Spaceship` does not have a two-argument constructor. I suspect that you expect `Spaceship s2(2322, "Kronas");` to become `Spaceship s2(Alien(2322, "Kronas"));`, but that's not how it works. – molbdnilo Feb 03 '21 at 08:28