1

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

11
  • Try to add () in between arrnode.push_back(((arr[j]=='(')?({1,1}):({-1,-1}))); Hope this help Commented Jul 22, 2013 at 11:38
  • @SatishBejgum No, it doesn't. Still a compiler error. Commented Jul 22, 2013 at 11:39
  • What you can do instead is arr[j] == '(') ? (node){1,1} : (node){-1,-1}, but I'm not sure it's standard (reminds me to C99 compound literals, and C99 isn't C++...) Commented Jul 22, 2013 at 11:40
  • 2
    Also, to @OP: Use whitespace. Please! Commented Jul 22, 2013 at 11:41
  • 1
    It is looking for an expression and {} are not in themselves an expression, if I understand correctly. I think section 8.5.4 of the standard is what you need, it covers where list initialization can take place and the ternary expression is not listed. Commented Jul 22, 2013 at 11:52

4 Answers 4

4

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 ) ); 
Sign up to request clarification or add additional context in comments.

2 Comments

And others have pointed out wrong. Whether if or a conditional operator is better depends on context; in this case, the important thing is the push_back (unconditional), so that should be put in evidence, rather than the reader having to analyze two branches, only to discover that they do exactly the same thing.
@JamesKanze That is a fair argument, I amended my answer.
1

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.

Comments

1

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.

Comments

0

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} ) ); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.