0

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.

Alex M
  • 54
  • 4
  • 2
    Please format this code a bit better, I can't make heads or tails out of it. – Frontear May 02 '19 at 13:01
  • *Why* do you think the cases 4 and 7 are incorrect? Why do you think the others are correct? – Some programmer dude May 02 '19 at 13:03
  • g++ claims 4 and 7 as incorrect (with little explanations): [**coliru**](http://coliru.stacked-crooked.com/a/ee6b8c87ef567d3d). – Scheff's Cat May 02 '19 at 13:11
  • 1
    What is the definition of "correct" here? From my point of view none of these are correct because 1) classes with non-trivial constructors should not have any public fields 2) there should be no implicit constructors (especially taking a single argument) 3) initialization should be performed using direct list initialization syntax 4) single letter names should not be used – user7860670 May 02 '19 at 13:11
  • 1
    What is the question? Do you want to know which of these are right/wrong, or how to fix these problems? – Constantinos Glynos May 02 '19 at 13:12
  • @AlexM 1) Please [edit] your question to include such information, instead of writing it in the comments. 2) "_No constructor for an int_" But, there exists implicit conversion from an integral value, to floating point value, doesn't it? – Algirdas Preidžius May 02 '19 at 13:14
  • 2
    Concerning 8): Following the answer of YSC, `C c(a)` can be constructed by `C::C(B b)` because `B::B(A a)` can be used for conversion of `a` to `class B`, and there is only one user-provided conversion necessary. – Scheff's Cat May 02 '19 at 13:19

1 Answers1

6

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).

YSC
  • 38,212
  • 9
  • 96
  • 149
  • So in that case, 4 and 7 don't work. So I suppose the answer is none? – Alex M May 02 '19 at 13:39
  • I was misunderstanding it as none of the other options, not none of the options. Like a different combination than the ones given is right or wrong. But using the is_convertible shows that A cannot be converted to C, so option e) seems correct in that case. – Alex M May 02 '19 at 13:50
  • @AlexM and if you're still unsure about the difference between `C c = A{}` and `C c{A{}}`, please do ask another question; we'd be happy to answer or point you to it. **edit**: never mind: https://stackoverflow.com/a/1051468/5470596 – YSC May 02 '19 at 14:04
  • 1
    Excellent, thank you for the sources/advice :) But if 8 is correct as well that seems to leave me with no correct options. If it was being called as "B b(5);" then it would be option c, but otherwise no option excludes only 4 and 7. – Alex M May 02 '19 at 14:41
  • Haha , that answer is good enough for me thank you again for all your help ! – Alex M May 02 '19 at 15:59