Any idea why the following snippet doesn't compile? It complains with an error "error: operands to ?: have different types"
auto lambda1 = [&](T& arg) {
...
};
auto lambda2 = [&](T& arg) {
...
};
auto lambda = condition ? lambda1 : lambda2;
use of ternary operator in lambda expression gives incorrect results.
You can use the ternary operator to assign references & const values where you would otherwise need to write a function to handle it: int getMyValue() { if( myCondition ) return 42; else return 314; } const int myValue = getMyValue();
both are fine. invalid lvalue in assignment. which gives error since in C(not in C++) ternary operator cannot return lvalue.
It is not faster. There is one difference when you can initialize a constant variable depending on some expression: const int x = (a<b) ?
Individual lambdas are translated to different classes by the compiler. For example, lambda1's definition is equivalent to:
class SomeCompilerGeneratedTypeName {
public:
SomeCompilerGeneratedTypeName(...) { // Capture all the required variables here
}
void operator()(T& arg) const {
// ...
}
private:
// All the captured variables here ...
};
Therefore, two different types are generated by the compiler, which causes a type incompatibility for auto lambda = condition ? lambda1 : lambda2;
The following would work:
auto lambda = condition ? std::function<void(T&)>(lambda1) : std::function<void(T&)>(lambda2);
To highlight that both lambdas are indeed different types, we can use <typeinfo>
from the standard library and the typeid
operator. Lambdas are not polymorphic types, so the standard guarantees that the 'typeid' operator is evaluated at compile time. This shows that the following example is valid even if RTTI is disabled:
#include <iostream>
#include <typeinfo>
int main()
{
struct T {
};
auto lambda1 = [&](T& arg) {
return;
};
auto lambda2 = [&](T& arg) {
return;
};
std::cout << typeid(lambda1).name() << "/" << typeid(lambda1).hash_code() << std::endl;
std::cout << typeid(lambda2).name() << "/" << typeid(lambda2).hash_code() << std::endl;
return 0;
}
The output of the program is (with GCC 8.3, see on Gobolt):
Z4mainEUlRZ4mainE1TE_/7654536205164302515
Z4mainEUlRZ4mainE1TE0_/10614161759544824066
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With