2010-11-04 21 views
2

Considérons les deux fonctions lambda dans 10,0 code du VC suivant:C++ 0x lambda valeur de retour des règles de type-inférence

template <typename T> 
void eq(uint fieldno, T value) { 
    table* index_table = db.get_index_table(fieldno); 
    if (index_table == nullptr) return; 
    std::set<uint> recs; 
    index_table->scan_index<T>(value, [&](uint recno, T n)->bool { 
     if (n != value) return false; 
     recs.insert(recno); 
     return true; 
    }); 
    add_scalar_hits(fieldno, recs).is_hit = 
     [=](tools::wsdb::field_instance_t& inst) { 
      return boost::get<T>(inst) == value; 
     }; 
} 

Dans la première fonction lambda, je suis obligé d'utiliser la spécification de type ->bool de retour alors que dans le deuxième lambda le compilateur était parfaitement heureux de déduire le type de retour.

Ma question est: quand le compilateur peut-il déduire le type de retour sur un lambda? Est-ce seulement quand vous avez un simple doublure?

Répondre

5

"Est-ce seulement quand vous avez une doublure simple?"

Oui. Selon le dernier C++ 0x publique projet (§5.1.2/4),

Si un lambda-expression ne comprend pas un type de fuite retour , il est comme si le arrière-retour de type désigne le type suivant:

  • si le composé énoncé est de la forme

    { returnattribut spécificateur optexpression; }

    le type de l'expression retournée après lvalue à rvalue conversion (4.1), la conversion à pointeur array (4.2), et la fonction à -pointer la conversion (4.3);

  • sinon, void.

[Exemple:

auto x1 = [](int i){ return i; }; // OK: return type is int 
auto x2 = []{ return { 1, 2 }; }; // error: the return type is void (a 
            // braced-init-list is not an expression) 

- exemple final]

Par conséquent, votre première expression lambda est interprété comme le retour void, ce qui ne va pas, donc vous devez ajouter un -> bool pour spécifier explicitement le type de retour.