1

So, a method would be to cout<<""; if the condition is false but I don't feel like it's the right way and break doesn't seem to work. Is there something I should know ?

template <class T>
T get(const string &prompt) {
    cout<<prompt;
    T ret;
    cin>>ret;
    return ret;
}
   int main()
{
    vector<int>x;
        for(int i=0;i<1000;i++) x.push_back((rand()%1200+1200));
    int rating=get<int>("Your rating: ");x.push_back(rating);
        sortVector(x);
    for(int i=0;i<x.size();i++) ((x[i]==rating) ? cout<<"Found your rating on pozition "<<i : cout<<"");
}
Stephen Newell
  • 7,330
  • 1
  • 24
  • 28
SKREFI
  • 177
  • 2
  • 13

5 Answers5

3

Each part of the ternary operator must be able to evaluate to the same type*, so you can't have one part output (which will return the cout object) while the other break's.

Instead, in your situation, why don't you add the condition to your for?

for(int i = 0; i < x.size() && x[i] == rating; i++) {
    cout<<"Found your rating on pozition ";
}

But this might not be what you actually want

It seems you're trying to find an item's position in the array. If this is the case, and you're only looking for the first occurence, I'd suggest this instead:

int pos;
for(pos = 0; pos < x.size() && x[pos] != rating; pos++) { }

if(pos != x.size()) {
    cout<<"Found your rating on pozition " << pos;
} else {
    cout << "Couldn't find it!";
}

Or even better, use std::find!


*You could also have a throw in there. Thanks to @Lightness!

scohe001
  • 15,110
  • 2
  • 31
  • 51
  • 2
    Almost true. You can in fact put a `throw` in there, for example. And if an expression it need only be _convertible_ to the same type. – Lightness Races in Orbit Mar 16 '18 at 20:29
  • 1
    You're on the right track, but this will print the string for every iteration until running out of elements or the element is found. – Some programmer dude Mar 16 '18 at 20:30
  • @LightnessRacesinOrbit Huh, I had no idea, but I guess it makes sense. Thanks for the tip! – scohe001 Mar 16 '18 at 20:32
  • OKay, very nice, thank you, don't know, didn't use 2 conditions in the for till now :D, now, I actually wanted to save that position in an other variable and I couldn't do it like this, thank you. – SKREFI Mar 16 '18 at 20:37
  • It is still one condition. – Lightness Races in Orbit Mar 16 '18 at 20:38
  • @Someprogrammerdude I just reread your comment and realize you were telling me my condition was flipped! Oops! Thanks for the catch :) – scohe001 Mar 16 '18 at 20:42
  • 1
    `i < x.size() && x[i] == rating` only works (coincidentally) if the very first element is `rating`, otherwise the condition's `false` when `i == 0` and the loop terminates immediately without doing anything. – Tony Delroy Mar 16 '18 at 20:48
  • @TonyDelroy It's my understanding that OP wanted a `break` where they have `cout << "";`, which would result in this behavior. – scohe001 Mar 16 '18 at 20:54
  • @scohe001: No, that behaviour is different. The condition needs to be flipped back. Trace your algorithm on paper and you will see. – Lightness Races in Orbit Mar 16 '18 at 20:59
  • 1
    @SKREFI if the `x[0]` is not equal to `rating`, the loop will break immediately. – R Sahu Mar 16 '18 at 21:03
  • @LightnessRacesinOrbit are you sure? His ternary would be `if(x[i] == rating) { cout << ...; } else { break; }` isn't that what my loop is emulating? – scohe001 Mar 16 '18 at 21:09
  • @scohe001: If that's really what he wants to do, the requirement is completely bonkers and would be better solved with something that is not a `for` loop (a simple comparison of `x[0]` would do). Tell you what, though, it does seem to be more of the OP's fault than yours, though, so I wish I could reverse my downvote. – Lightness Races in Orbit Mar 16 '18 at 21:11
  • @LightnessRacesinOrbit Ha, you're not wrong. I added a second part to the answer to take care of the "bonkers" :) – scohe001 Mar 16 '18 at 21:15
  • @RSahu yes =)), that was a logical issue, I figured that out, someone else spoted it, thank you anyways <3 – SKREFI Mar 16 '18 at 21:15
  • That's better now. Two comments - what if no match is found? And prefer `{}` to `;` so some nitwit doesn't remove it later thinking it's a typo. – Lightness Races in Orbit Mar 16 '18 at 21:58
  • @LightnessRacesinOrbit good calls all around. Fixed to incorporate your advice. – scohe001 Mar 16 '18 at 22:29
3

Use of the conditional operator is not the best strategy for what you are trying to do.

Simplify your code. Use if-else.

for(int i = 0; i < x.size(); i++) 
{
   if (x[i] == rating)
   {
      std::cout << "Found your rating on position " << i << ".\n";
      break;
   }
   else
   {
      std::cout << "Still looking for your rating.\n";
   }
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • @TonyDelroy, I think the OP accepted the wrong answer :) – R Sahu Mar 16 '18 at 20:56
  • Yea, obviously I could use it, but I wanted to learn about this conditional operator, why nobody understands this ? I want to do it that way to learn those features. Sure I could use some ifs and a few lines for and do the job, but I want to learn about those things. – SKREFI Mar 16 '18 at 20:59
  • @TonyDelroy Yea :D, you right, but I used that with a condition in the for . That was a logical issue anyways.. – SKREFI Mar 16 '18 at 21:00
  • 1
    @SKREFI, what I am saying by "I think the OP accepted the wrong answer" is that if you use the accepted post's solution, you will get an incorrect answer. – R Sahu Mar 16 '18 at 21:01
  • 1
    @SKREFI: _"I wanted to learn about this conditional operator, why nobody understands this ?"_ We do understand this. That is why we are spending time on Friday night to teach you about it, including when not to use it. Why do you not understand this? – Lightness Races in Orbit Mar 16 '18 at 21:03
  • Well, I still don't understand why not to use it, I mean, yeah, not the best situation to do so, I only read about the benefits about it (https://stackoverflow.com/questions/3312786/benefits-of-using-the-conditional-ternary-operator) and the way you are spending your time it's your own choice. – SKREFI Mar 16 '18 at 21:21
  • @SKREFI: Just because we chose to spend our time helping you doesn't mean you shouldn't be grateful for it. Are you only grateful for slave labour? – Lightness Races in Orbit Mar 16 '18 at 22:34
  • @LightnessRacesinOrbit, do you have a problem with people who have a sense of entitlement? :) :) – R Sahu Mar 16 '18 at 22:37
  • @RSahu: I'm perfectly entitled to do so. – Lightness Races in Orbit Mar 16 '18 at 22:43
3

You don't.

Get rid of the crypticism, and write out a proper if statement like everybody else.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • I want it more fancy, to code in more complex and efficient way... what's the problem ? – SKREFI Mar 16 '18 at 20:34
  • 1
    @SKREFI: The problem is exactly why you had to come here asking how to break out of the loop: you are trying to use a language feature that is meant for something else, for the sake of being "more fancy" and "more complex". That is _less_ efficient in so many ways. Just use the right tool for the job, and save your energy for the truly important challenges. – Lightness Races in Orbit Mar 16 '18 at 20:35
  • @SKREFI: Instead of being "fancy", write simple, easy-to-maintain code that everybody can understand (including your computer). – Lightness Races in Orbit Mar 16 '18 at 20:39
  • 1
    Well, I am looking to learn those tools, that's why I use those. It wouldn't help mutch me improving my coding skills using the basics I guess. I am sure you right about the efficiency but still, I want to use those to learn it. – SKREFI Mar 16 '18 at 20:42
  • 1
    @SKREFI: Part of learning about tools is learning when _not_ to use them. This is one of those times. – Lightness Races in Orbit Mar 16 '18 at 20:56
2

It's possible with the GNU statement-expression extension: ({ break; }) is an expression of type void.

But there is never reason to do that except in case of extreme macro hackery, which you probably shouldn't be doing yourself anyway.

o11c
  • 15,265
  • 4
  • 50
  • 75
0

You can't use break in a conditional. To hack this up using a non-throwing conditional (for educational purposes per your comments), you actually need it in the for loop as follows:

for (int i = 0; i < x.size(); i = x[i] == rating
                                  ? ((cout << "found at " << i), x.size())
                                  : i + 1)
    ;

What this does is advance i to x.size() (so the loop will terminate) when the rating is found (after evaluating output and ignoring it using the comma operator), otherwise moving i to the next element index (i + 1). Put another way, the use of the conditional operator above is equivalent to:

if (x[i] == rating)
{
    std::cout << "found at " << i;
    i = x.size(); // poor man's "break"
}
else
    i = i + 1;

(You could of course put the code immediately above in the statement controlled by your for loop... for (size_t i = 0; i < x.size(); ) if (x[i] == ...), but then you wouldn't be using the conditional operator (and could use an actual break, and might as well use ++i in the for advancement statement and ditch the else above, at which point you have R Sahu's answer).

I put a complete demo program on coliru.stacked-crooked.com.


As I mentioned in a comment, you can't break in a conditional, but you can throw. Using exceptions for an event you expect to occur is generally frowned upon (a coding convention that reserves them for unexpected events helps other programmers understand how you're expecting your program to run), but it's possible:

int main()
try
{
    ...
    for (size_t i = 0; i < x.size(); ++i)
        x[i] == rating ? throw i : (void)0;
}
catch (size_t i)
{
    std::cout << "found at " << i << '\n';   
}

You can find/run/edit this on coliru here. Note (void)0 is evaluated but does nothing - it has no side effects. You could use any expression there - 0, 'x', nullptr - but prefixing with (void) emphasises that the value can't and won't be read and used for anything. So it would be equivalent, clearer and more concise to use if (x[i] == rating) throw i; if we weren't set on using the conditional operator.


How you should actually write it if you're not trying to teach yourself how to abuse conditional operators:

std::cout << "found at " << x.find(rating) - x.begin() << '\n';

Often when you use find you should be checking against x.end() to see if your value was found, but in your case you know 100% that the value is in the vector so can safely keep the code simple.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • Wow, that's a bit complicated for me =)) I don't understand this part: i = x[i] == rating. – SKREFI Mar 16 '18 at 21:25
  • @SKREFI What it's doing is assigning the next value to `i`, but which value is assigned depends on whether the value of `x[i]` is currently `rating`. If so, then it assigns the "`?` value" of `x.size()` (so `x < x.size()` will fail and the loop will break), otherwise it assigns `i + 1` to advance through the vector. It's further complicated by the use of the comma operator in `(std::cout << ..., x.size())` - what that does is output first, but still evaluate to `x.size()`. Weird operator, right? ;-) Hopefully this shows you can learn some interesting new stuff from your question! – Tony Delroy Mar 16 '18 at 21:31
  • Hehe... nobody appreciates seeing the question - *"How to break a for loop in Ternary Operator"* actually addressed.... – Tony Delroy Mar 16 '18 at 22:07
  • Yeah, pretty weird, but I think I got it (I hope :D), thank you very much. – SKREFI Mar 17 '18 at 07:56