using ternary operator with overloaded constructor

hi, I have two possible questions; can you use a ternary operator to initialize objects with overloaded constructors like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

class thing
{
   int x;
   int y;
   int z;

   thing(int g)
   {
       x=0;
       y=0;
       z=0;
   }
   otherThing(int a, int b, int c)
   {
       x=a;
       y=b;
       z=c;
   }
}

int main()
{
    int Q;
    int R;
    int S;

    bool d;

//assume all of the above are given values here by the user

    //either this
    thing objectThing( d ? (0):(Q, R, S) );
    //calling the first works, but calling the second option breaks the program


    // or this
    (d ? (thing objectThing(0)) : (thing objectThing(Q,R,S)) );
    // but this doesn't compile

    return 0;
}

I can get around it if I need to but I'd like to learn more about the ternary operator if I can, since I couldn't find anything online that addressed this particular issue, at least in a way I could detect.
So why exactly do these examples not work?
Thanks for any help
Line 14: Are you intending this to be a constructor? If so, it must be named the same as your class.

Line 20: Your class needs a closing ;

Line 33: This isn't doing what you expect. A ternary operator is an expression. It selects one of two values based on a condition. You're also misusing the comma operator here. The comma operator will evaluate each of the three expressions in the parenthises, but use only the last.
http://www.cplusplus.com/doc/tutorial/operators/
So we can simplify line 33 as:
thing objectThing( d ? 0 : S);
That's a valid expression since the ternary operator resolves to one of two ints and thing has a constructor that accepts a single int.

Line 38 is not valid because each side of the ternary expression is defining an object instance, not a value.





A trinary expression has the following grammar: expr ? expr : expr. At a posterior step in the compilation process, the first expression is checked for convertibility to bool, and the second and third expressions are checked to be of the same type (more or less).

Your first example simply calls thing::thing(int) because the type of (Q, R, S) is int, and its value is S (see the semantics of the comma operator for more information). At a more fundamental level, you're using (Q, R, S) as if it was a parameter list. A parameter list is not an expression, so it can't be an operand of ?:.

Your second example fails to compile because you're using object declarations as operands for ?:, which are not expressions.

You could do
 
thing objectThing(d ? thing(0) : thing(Q, R, S));
But it is possible using dynamic allocation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

struct foo
{
    foo(){}
    foo(int){}
};

int main()
{
    bool baz;
    std::cin >> baz;
    foo* bar = (baz ? new foo(): new foo(2));
}
Or it is possible to bind different variables to the reference using ternary operator:
1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main()
{
    int x = 1, y = 2;
    bool b;
    std::cin >> b;
    int& z = (b ? x : y);
    std::cout << z;
}


Ok, that makes sense if it can only take expressions. I had seen you could make function calls inside it so I thought maybe you could construct objects too, but its clear those are very different things from at least the operator's point of view.
thanks all
Topic archived. No new replies allowed.