-1

I am trying make ternary operator work with lambda. Following is the logic that I want to cast into a ternary operation

if (boolean_condition_var == false) {
  RandomMethod();
}

// From here some logic to execute
int i = 0;
// blah blah logic

Following is how I am trying to make it work after reading through this link.

boolean_condition_var == false ? RandomMethod() : std::function<void(void)>([this](){
    // execute some logic here
    int i = 0;
    //blah blah logic
});

But I am getting the following error:

Issue:

error: left operand to ? is void, but right operand is of type 'std::function<void ()>'
boolean_condition_var == false ? RandomMethod() : std::function<void(void)>([this](){ int i = 0; });

Question:
How can I pass a lambda into the second clause of my ternary operator?

TheWaterProgrammer
  • 7,055
  • 12
  • 70
  • 159
  • s/`RandomMethod()`/`RandomMethod` – user0042 Sep 17 '17 at 15:23
  • You are missing `()` after the declaration to trigger the execution. So it's just what the compiler said it would be: An `std:: function`, and not the return value of such. – Ext3h Sep 17 '17 at 15:25
  • @Ext3h Depends on what the whole expression should evaluate to. Seems like the OP want's to evaluate a `std::function`. – user0042 Sep 17 '17 at 15:29
  • 6
    If your function and the alternative lambda return `void`, using a ternary operator is rather convoluted, and accomplishes nothing useful. A simple `if`/`else` does the same thing, and is much more readable. – Sam Varshavchik Sep 17 '17 at 15:29
  • I want to call a method in the first clause & execute a lambda in the second. isnt that possible here? – TheWaterProgrammer Sep 17 '17 at 15:31
  • _@Programist_ OK, I got your statement wrong. Stick with `if() else` then as @Sam proposed. – user0042 Sep 17 '17 at 15:36
  • 5
    `boolean_condition_var == false` does not establish the condition aggressively enough. I suggest `(boolean_condition_var == false) == true` for some extra punch, or if you want to be even more assertive, `((boolean_condition_var == false) == true) != false)`. – n. m. could be an AI Sep 17 '17 at 15:37
  • @n.m. That kind of manual brainless coding is what templates where designed to write for you. Use a pack of trues and falses and left fold in order to automate that expansion everywhere you need it. – Yakk - Adam Nevraumont Sep 17 '17 at 15:40
  • I'm not sure I understand this at all. You want to either call a method, or have an immediately evaluated lambda, or return the lambda? Or what? – Nir Friedman Sep 17 '17 at 15:42
  • 1
    @programist Why do you want to? I mean that extemely specifically. "I want to pass a lambda as the srcond argument" *in order to do ehat exactly?*, because why you are doing it changes how you do it. "I want a red car on this road" has a different answer *if you want to drive it afterwards*, or just keave it there, or what directiin the car is going to go. Please post what you want to happen *in observable program behaviour* after you get your code working. – Yakk - Adam Nevraumont Sep 17 '17 at 15:43
  • 1
    ^That. You have no syntax errors, `auto b = condition ? []{} : []{};` __will__ compile. You are asking the wrong question – Passer By Sep 17 '17 at 16:26
  • 1
    @passerby `condition?[&]{}:[&]{}` will not. – Yakk - Adam Nevraumont Sep 17 '17 at 17:20
  • @PasserBy `boolean_condition_var? ([this](){...your code...}) ( ) : RandomMethod();` passes 2 lambdas into both the conditions of the ternary operator. that is close to what am looking for but the accurate answer to my question would be pass a lambda only to one clause of the ternary operator. thanks for this solution anyways – TheWaterProgrammer Sep 17 '17 at 19:32

2 Answers2

1

How can I pass a lambda into the second clause of my ternary operator?

Using comma operator ?

boolean_condition_var == false 
       ? (RandomMethod(), 0)
       : (std::function<void(void)>([this](){ /*...*/ })(), 0);

Or, I suppose better,

std::function<void(void)> logicElse { [this](){ /*...*/ } };

boolean_condition_var == false 
       ? (RandomMethod(), 0)
       : (logicElse(), 0);
max66
  • 65,235
  • 10
  • 71
  • 111
1

Since you are not calling the lambda, it makes little sense to create it. What you are trying to do is equivalent to

boolean_condition_var ? void(0) : RandomMethod();

On the other hand, if you want to call the lambda, use the call operator:

boolean_condition_var? ([this](){...your code...}) ( ) : RandomMethod();
//                                                  ^
//                                                  |
//--------------------------------------------------+

There's no need to cast anything to std::function.

A plain old if-then-else statement would be more welcome here.

On the third hand, if you want your ternary operator to return a callable, you probably need something like

 using voidf = std::function<void(void)>;

 auto result = boolean_condition_var?
     voidf([this](){...your code...}):
     voidf([this](){RandomNethod();});

 .... result();

Capturing boolean_condition_var by value and moving the condition into the (now single) lambda could be more readable and more efficient though.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243