Alex M
Alex M

Reputation: 54

How to correctly initialize a Struct in c++

Currently running into an issue with this question in my homework. I believe that only 4,7 are incorrect (In Visual Studio they don't throw an error). But i'm honestly not sure why they are the only ones. Since 3 works, I assumed they would work as well but that seems to not be the case. Any advice?

struct A {
    double x;
    A(double x = 1) : x(x) { }
};

struct B {
    double x;
    B(A a = 2.0) : x(a.x) { }
};

struct C {
    double x;
    C(B b = B(3)) : x(b.x) { }
};

int main() {
    A a; // (1)
    A a = 4; // (2)
    B b; // (3)
    B b = 5; // (4)
    B b(a); // (5) (a is an object of class A)
    C c; // (6)
    C c = 6.0; // (7)
    C c(a); // (8) (a is an object of class A)
    C c(b); // (9) (b is an object of class B)
}

Correct ones are:

a) 1-3

b) 1-3,5,9

c) 1-6,8,9

d) 1-7

e) 1-3,5,6,9

f) none

My reasoning:

1) Correct, just default constructor

2)Correct, constructor default or value (4)

3) Correct, default constructor

4) Incorrect, No constructor for an int

5) Correct, exists constructor for object of type A

6) Correct, Default

7)Incorrect, same as 4

8) This one i'm not sure on, there is no constructor for objects of type A, so I would say incorrect

9) Correct, constructor exists.

This is my reasoning in any case, but i'm not sure where i'm going wrong.

Upvotes: 0

Views: 120

Answers (1)

YSC
YSC

Reputation: 40150

The rule is, when converting from a type to another (here from/to int, double, A, B or C): only one user-provided conversion can be used.

This makes indeed B b = 5; // (4) invalid since 5 (an int) needs to be:

  • converted to double (first standart-conversion),
  • then to a A (first user-defined conversion),
  • then to a B (second user-defined conversion).

That last one breaks the rule, and this conversion sequence is not legal.

I'm honestly not sure why they are [ incorrect ].

You can use this rule to check other expressions.


Finally, you can impress your teacher with std::is_convertible:

std::is_convertible_v<B, C> returns true iff B is convertible to C (demo).

Upvotes: 6

Related Questions