ラムダのC++三元割り当て




c++11 lambda (4)

2つのlambdas( lambda1 および lambda2 )は2つの異なる型であるため、 ?:lambda1 および lambda2 から lambda 戻り値の型を推定できません。 これは、これら2つが相互に変換可能でないために発生します。

次のスニペットがコンパイルされない理由は何ですか? 「error:operands to?:have different types」というエラーで文句を言います

  auto lambda1 = [&](T& arg) {
      ...
  };
  auto lambda2 = [&](T& arg) {
      ...
  };
  auto lambda = condition ? lambda1 : lambda2;

コンパイラは auto タイプを決定できません。

auto lambda = condition ? lambda1 : lambda2;

すべてのラムダには異なる一意の型があるためです。

動作する1つの方法は次のとおりです。

auto lambda = [&](T& arg) {
     return (condition ? lambda1(arg) : lambda2(arg));
}

各ラムダには一意の型があるため、コンパイルされません。 ?: 共通の型はありません。

それらを std::function<void(T&)> でラップできます。例えば

auto lamba1 = [&](T& arg) {
  ...
};
auto lambda2 = [&](T& arg) {
  ...
};
auto lambda = condition ? std::function(lambda1) : lambda2; // C++17 class template deduction

興味深いことに、ラムダがキャプチャレスの場合、演算子 + トリックを使用できます。

auto lambda1 = [](int arg) { ... };
auto lambda2 = [](int arg) { ... };

auto lambda = condition ? +lambda1 : +lambda2; // This compiles!
lambda(2019); 

これは、 + がラムダを関数ポインターに変換し、両方の関数ポインターが同じタイプ( void (*)(int) ようなもの)を持っているためです。

GCCとClang(ただしMSVCではない)では、 + を省略できますが、ラムダは引き続き関数ポインターに変換されます。





conditional-operator