11

Let's say I have a C++ class with two functions like

class MyClass
{
    bool Foo(int val);
    bool Foo(string val);
}

Is it possible to use the ternary operator like this

MyClassInstance->Foo(booleanValue?24:"a string");

and have a different function of MyClass invoked depending on the value of booleanValue?

Stals
  • 1,543
  • 4
  • 27
  • 52
Yannick Blondeau
  • 9,465
  • 8
  • 52
  • 74
  • 6
    Have you tried compiling and running it to see what happens? – Dan F Oct 24 '12 at 13:22
  • This doesn't even compile. The compiler will complain about the different types of the ternary operator. – Olaf Dietsche Oct 24 '12 at 13:26
  • 4
    I do not understand the upvotes here. Sure, it's a fun experiment, but the question could have easily been avoided if the OP only *tried it*. The OP has not provided any research information at all. – default Oct 24 '12 at 13:27
  • I came from a PHP background and I got 3 downvotes immediately. damn some languages are just stubborn isn't it? – mauris Oct 24 '12 at 13:33
  • 1
    @Default I should have phrased my question differently: I have that code that does not compile, is there a way to get it compiling or is this notation forbidden? I will be more careful next time... – Yannick Blondeau Oct 24 '12 at 13:55

4 Answers4

25

Not with the ternary operator. The type of a ternary expression is the common type of its second and third operands; if they have no common type you can't use it. So just use an ordinary if statement:

if (booleanValue)
    MyClassInstance->Foo(24);
else
    MyClassInstance->Foo("a string");
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
7

The type of a ternary conditional expression is the common type two which both operands are con­ver­tible. You can definitely not perform "dynamic overload resolution", as you seem to be suggesting.

Since there is no common type for int and char const *, the code won't even compile (as you sure­ly noticed when you tested this).

(You may be thrilled to know that the ternary conditional is used precisely because of those semantics in the implementation of the std::common_type trait class template, together with decltype.)

(If the condition is known statically, such as sizeof(int) != 7, then you can use template spe­cia­lization to write similar-looking code that does perform conditional overload resolution, but of course statically.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
5

No. To perform overload resolution the compiler will ask "what is the type of booleanValue?24:"a string"?". That question cannot be answered.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • Cannot be answered *at compile-time* (not my down-vote BTW - just making a small suggestion to improve the answer) – Paul R Oct 24 '12 at 13:23
  • @Paul In C++ expressions only have types at compile-time. It does not make sense to talk about something else. – R. Martinho Fernandes Oct 24 '12 at 13:24
  • Yes, I know, the point is that it is *conceivable* that you could determine which function to call dynamically, i.e. at run-time, but for C++ you need to know the type at compile-time. – Paul R Oct 24 '12 at 13:26
5

No, this is not permitted.

Overloads are compile-time, so it cannot work in runtime that way.

It is not common in code you would want to do exactly that, however sometimes with iostream there is a desire to do something like:

os << ( condition ? var1 : var2 )

where var1 and var2 have different types. That also doesn't work.

You could do:

MyClassInstance->Foo( booleanValue ? boost::any(24) : boost::any("a string") );
CashCow
  • 30,981
  • 5
  • 61
  • 92