2017-09-03 2 views
3

Qu'est-ce qui disqualifie la capture de lambda d'être passé à la méthode apply de std::valarray? considérer le code suivant:Pourquoi le lambda de capture ne peut-il être appliqué à std :: valarray?

int main() 
{ 
    std::valarray<int> arr = {1, 2, 3, 4, 5, 6}; 
    auto arr1 = arr.apply([](int val) { return val * 2; }); // compiles 
    int n = 3; 
    auto arr2 = arr.apply([n](int val) { return val * n; }); //does not compile 
    return 0; 
} 

en direct sur coliru http://coliru.stacked-crooked.com/a/f0407046699574fc

Testé sur https://gcc.godbolt.org/
Ni GCC, ni MSVC ou Clang compilerait le code ci-dessus

Répondre

3

La raison en est dans la définition de std::valarray::apply:

valarray<T> apply(T func(T)) const; 
valarray<T> apply(T func(const T&)) const; 

Le type de func dans les deux membres est un type de fonction. Qui, lorsqu'il est utilisé en tant que type de paramètre d'une autre fonction, se décompose en un pointeur de fonction. Ces fonctions membres n'acceptent pas les foncteurs généraux. Seuls les pointeurs vers les fonctions régulières. Maintenant, un lambda sans capture a un opérateur de conversion implicite à un pointeur de fonction. Donc le premier lambda est converti en un int(*)(int) qui est une adresse de fonction régulière qui peut exécuter le corps lambdas.

Mais les lambdas qui capturent l'état ne peuvent pas être convertis de cette manière, et comme vous pouvez le voir, ne peuvent pas être passés en argument à std::valarray::apply.

+0

une idée de pourquoi cela a été fait en premier lieu? peut-être parce que cela rendrait les optimisations de vectorisation ou de parallélisation non applicables sur une telle implémentation 'apply'? – kreuzerkrieg

+0

@kreuzerkrieg - 'std :: valarray' a été conçu longtemps avant que lambdas ne soit introduit dans la langue. Aussi, j'imagine que c'est encourager les fonctions "pures". En C++ moderne, cela se démarque, je sais. – StoryTeller

+0

ummm ... ils ont ajouté des spécialisations std :: begin/fin pour C++ 11 pour valarrays, pourquoi ne pas ajouter le reste des trucs modernes ... Eh bien, je suppose que le valarray n'est pas aussi largement utilisé que le reste de Conteneurs STL. – kreuzerkrieg