AvinashK
AvinashK

Reputation: 3423

compiler not accepting ternary operator's use

I have a char vector arr and a vector arrnode which has its elements as node. Following is the code:

struct node
{
    int min;
    int sum;
};

vector<char> arr;
char c;

for(int j = 0; j < n; j++)
{
    cin >> c;
    arr.push_back(c);

}

vector<node> arrnode;
for(int j = 0; j < n; j++)
{
  /* if(arr[j]=='(')
       arrnode.push_back({1,1});
       else
      arrnode.push_back({-1,-1});*/

      arrnode.push_back( ( ( arr[j]=='(' ) ? {1,1} : {-1,-1} ) );

}

This code gives the following error for the line where ternary operator is used.

prog.cpp:68:49: error: expected ‘:’ before ‘{’ token
prog.cpp:68:49: error: expected primary-expression before ‘{’ token

However, the if-else part(which is commented) makes the code work fine. What am I missing? Thanks in advance and sorry for the shabby title of the question :)

Upvotes: 1

Views: 790

Answers (4)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158489

So using gcc the error you see will look something like so:

error: expected primary-expression before ‘{’ token

It is expecting an expression but {}s are not an expression, they are just usable for list initialization in some places as specified by section 8.5.4 of the draft standard, which says:

... List-initialization can be used

— as the initializer in a variable definition (8.5)

— as the initializer in a new expression (5.3.4)

— in a return statement (6.6.3)

....

It does not list the conditional operator. As others have said an alternative is to use an if statement. Although as James points out this may not be the ideal substitution, so if you feel that the conditional operator works better in your context then as James suggests just use the following:

arrnode.push_back( arr[j] == '(' ? node( 1, 1 ) : node( -1, -1 ) );

Upvotes: 4

Zecharye Galitzky
Zecharye Galitzky

Reputation: 26

In C you would write:

 arrnode.push_back( ( ( arr[j]=='(' ) ? (node){1,1} : (node){-1,-1} ) );

But in C++ "Compound literals" are not allowed so you can write:

 arrnode.push_back( ( ( arr[j]=='(' ) ? node{1,1} : node{-1,-1} ) );

Upvotes: 0

parkydr
parkydr

Reputation: 7782

The problem is that in the ternary operator the compile can't tell the type, it's just an initialiser, so you need

arrnode.push_back((arr[j]=='(')? node({1,1}) : node({-1,-1}));

Your construct is not the same as the if, it's more like

if(arr[j]=='(')
  x={1,1};
else
  x={-1,-1};
arrnode.push_back(x);

x has no type.

Upvotes: 1

James Kanze
James Kanze

Reputation: 153929

The syntax doesn't allow it. And how could it: what is the type of { 1, 1 }? (The compiler must determine the types in a conditional expression.)

Rather than being fancy, why not just write:

arrnode.push_back( arr[j] == '(' ? node( 1, 1 ) : node( -1, -1 ) );

It's clearer when you state the type explicitly, not only for the compiler, but for the human reader.

Upvotes: 1

Related Questions