Ternary operator help

I'm looking at the ternary operator and I never used it before but would liek to know how it works, I've been looking at documentation for it but it doesnt say what exactly ? does and : does, i've just seen example of its use, what does the question mark mean? can there be multiple of them? what about the colon? what exactly does that do in the statement? can there be multiple of that as well?

Could you please give a few examples?

some_condition ? if_that_condition_was_true_this : otherwise_this

That's all there is to it.
Last edited on
would I be able to translate this to a ternary expression?

1
2
3
4
if(m_magazineCapacity < 0 || fireAmount > m_magazineCapacity)
            {
                throw std::invalid_argument("Error, magazine capacity too low or fire amount greater than magazine capacity of weapon.");
            }


If so i'm a little confused as to how exactly do it. As a side question, is there any way to store that thrown exception in a variable and call it like: throw negativeAmmoException?
Last edited on
No, you can't use the conditional (a.k.a., "ternary") operator there.
It's an expression, not a statement, so it evaluates to a value, which is usually assigned to a variable or passed to a function.
It's used in situations like this:

1
2
3
4
5
6
7
8
9
int a = (x > y) ? 42 : 24;   // The parens around x > y are not necessary

// which is equivalent to this:

int a;
if (x > y)
    a = 42;
else
    a = 24;

Another example:

1
2
3
4
5
6
7
8
9
10
11
my_function(123, x > y ? 1 : 2);

// which is equivalent to:

int tmp;
if (x > y)
   tmp = 1;
else
   tmp = 2;

my_function(123, tmp);

Sometimes people misuse it as a statement replacing an if statement, like this:

1
2
3
4
5
(x > y) ? cout << "yes" : cout << "no";
    
// But that's just stupid. Although it's reasonable to do this:

cout << (x > y ? "yes" : "no");  // parens necessary here due to low precedence of ?: 

As for storing the exception in a variable:

1
2
3
4
5
6
7
std::invalid_argument negativeAmmoException(
    "Error, magazine capacity too low or fire amount greater than magazine capacity of weapon.");

if (m_magazineCapacity < 0 || fireAmount > m_magazineCapacity)
{
    throw negativeAmmoException;
}

Last edited on
Would I be able to translate this to a ternary expression?

Yes, even without any trickery: the standard special-cases it.
1
2
3
m_magazineCapacity < 0 || fireAmount > m_magazineCapacity
  ? throw std::invalid_argument{""}
  : (void)0;
Last edited on
That's a good example of a stupid use of the conditional operator.
What's the point?
What's the point?

There is no point, but that's how you do it.
Last edited on
Using a throw expression as one of the operands of the conditional operator is useful in situations where the initialisation of an object that is expensive to construct is involved.

For example:
1
2
3
4
5
6
struct foo
{
    explicit foo( std::string str ) : b( str.size() < 5 ? throw "bad arg" : str ) {}

    bar b ; // bar is expensive to construct/destroy
};


In contrast, this would require the construction and destruction of a bar object if the argument is invalid:
1
2
3
4
5
6
7
struct foo
{
    explicit foo( std::string str ) : b(str)
    { if( str.size() < 5 ) throw "bad arg" ; }

    bar b ; // bar is expensive to construct/destroy
};



These are some of the permissible ways in which the conditional operator can be used:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <stdexcept>

int main()
{
    int x = 9, y = 6, z = 0 ;

    ( x>y ? ( std::cout << "yes" ) : ( std::cout << "no" ) ) << '\n' ; // yes

    z = x>y ? 23 : throw std::invalid_argument("blah!") ; // int z = 23 ;

    try { z = x<y ? 999 : throw std::invalid_argument("blah!") ; } // throws
    catch( const std::exception& e ) { std::cout << e.what() << '\n' ; } // blah!

    // if x>y, add 10 to x, else add 10 to y
    ( x>y ? x : y ) += 10 ; // x += 10 (x any y are lvalues of the same type)

    std::cout << x << ' ' << y << ' ' << z << '\n' ; // 19 6 23
}

http://coliru.stacked-crooked.com/a/3d3d5b83dfa8e7e4
Great! thank you for all your help!
Topic archived. No new replies allowed.