Question

J'ai rencontré un problème étrange. Le code simplifié suivant reproduit le problème dans MSVC 2010:

template <typename T>
struct dummy
{
    static T foo(void) { return T(); }
};

int main(void)
{
    typedef dummy<bool> dummy_type;
    auto x = []{ bool b = dummy_type::foo(); };
    // auto x = []{ bool b = dummy<bool>::foo(); }; // works
}

Le typedef j'ai créé localement dans la fonction ne semble pas être visible dans le lambda. Si je remplace le typedef avec le type réel, il fonctionne comme prévu.

Voici quelques autres cas de test:

// crashes the compiler, credit to Tarydon
int main(void)
{
    struct dummy {};

    auto x = []{ dummy d; };
}

// works as expected
int main(void)
{
    typedef int integer;

    auto x = []{ integer i = 0; };
}

Je n'ai pas g ++ disponible pour le tester, en ce moment. Est-ce une règle étrange dans C ++ 0x, ou tout simplement un bogue dans le compilateur?

A partir des résultats ci-dessus, je me penche vers bug. Bien que l'accident est sans aucun doute un bug.


Pour l'instant, je l'ai déposé deux rapports de bogue .

Tous les extraits de code doivent compiler ci-dessus. L'erreur doit faire avec l'aide de la résolution de portée sur les étendues définies localement. (Repéré par dvide .)

Et le bug de plantage doit faire avec ... qui sait. :)


Mise à jour

Selon les rapports de bogue , ils ont tous deux été fixés pour la prochaine version de Visual studio 2010. (Bien que cela ne semble pas être le cas,. VS11 peut-être)

Était-ce utile?

La solution

De N3000, 5.1.2 / 6,

  

Le lambda de l'expression   instruction_compound donne le   fonction-corps (8,4) de la fonction   appel opérateur, mais à des fins de   recherche de nom (3.4), ... la   -Instruction composée est considérée dans   le contexte du lambda-expression.

Sans surprise, le type local doit être visible.

Autres conseils

ne peuvent pas être détectés énumérations de fonction locale par lambdas soit.

int main()
{   
    enum E {A, B, C};   
    auto x = [](){ int a = A; }; 
    //auto y = [](){ E a = A; }; // this will crash the compiler
}

erreur C3493: « A » ne peut pas être capturé implicitement parce qu'aucun mode de capture par défaut a été spécifié

Voici une workround, problématique, peut-être bien.

int main()
{   
    enum E {A, B, C};   
    auto x = [=](){ int a = A; };
    // typedef E F; 
    // auto y = [=](){ F a = A; }; // this compiles ok
}

Ce n'est pas vraiment une réponse à votre question, mais simplement d'explorer le problème. Je me demandais si le compilateur a des problèmes traitant de types a déclaré dans une portée englobante, donc essayé ceci:

#include <iostream>

template <typename Func>
void do_test(Func pFunc) {
}

template <typename T>
void test_trait(void) {
   class Something { public: int foo; };

   do_test ([] (T pX) {
      Something A; A.foo = 12;
   });
}

int main(void) {
    test_trait<int> ();
}

Ici, je vais juste essayer de créer un type local dans le périmètre qui entoure et l'utiliser dans la fonction lambda. Non seulement cela ne compile pas (avec Visual Studio 2010, Beta 2), mais il se bloque en fait le compilateur avec une erreur interne C1001.

Je l'ai déposé deux rapports de bogues.

Nous verrons comment ça se passe. :)


Mise à jour

Les deux bugs ont été marqués comme fixes:

  

Nous apprécions vos commentaires. Ce bug a été vu par nous avant et nous l'avons fixé à la prochaine version. Merci d'utiliser le produit.

     

Merci,
  Ulzii Luvsanbat
  Windows équipe C ++

Alors là, nous allons.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top