Frage

Ich habe in ein seltsames Problem laufen. In der folgenden vereinfachten Code reproduziert das Problem in 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
}

Die typedef I erstellt lokal in der Funktion scheint nicht in dem Lambda sichtbar zu sein. Wenn ich die typedef mit dem tatsächlichen Typ ersetzen, es funktioniert wie erwartet.

Hier sind einige andere Testfälle:

// 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; };
}

Ich habe nicht g ++ zur Verfügung zu testen, gerade jetzt. Ist das eine seltsame Regel in C ++ 0x, oder einfach nur um einen Fehler im Compiler?

Aus den Ergebnissen oben, ich bin Neigung in Richtung Bug. Obwohl der Absturz ist auf jeden Fall ein Fehler.


Im Moment habe ich zwei Bugreports eingereicht .

All Code-Schnipsel soll über kompilieren. Der Fehler hat mit der Verwendung der Bereichsauflösungs auf lokal definierte Bereiche zu tun. (Spotted by DVide .)

Und der Absturz Fehler zu tun haben, mit ... wer weiß. :)


Update

Nach dem Bugreports sie haben feste sowohl für die nächste Version von Visual Studio 2010 (Obwohl dies nicht der Fall scheint zu sein,. VS11 vielleicht)

War es hilfreich?

Lösung

Von N3000, 5.1.2 / 6,

  

Der Lambda-Ausdruck ist   Verbindung-Aussage ergibt den   Funktionskörper (8.4) der Funktion   Telefonist, aber für die Zwecke der   Namenssuche (3.4), ... die   Verbindung-Anweisung wird als in   der Kontext des Lambda-Ausdruck.

Es überrascht nicht, sollte der lokale Typ sichtbar sein.

Andere Tipps

Function-local Aufzählungen können auch nicht durch lambda nachgewiesen werden.

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

Fehler C3493: ‚A‘ kann nicht implizit, weil kein Modus Standard-Capture erfasst werden angegeben wurde

Es folgt eine workround, problematisch, vielleicht aber.

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

Das ist nicht wirklich eine Antwort auf Ihre Frage, aber nur das Problem weiter zu erforschen. Ich frage mich, ob der Compiler Probleme hat den Umgang mit Typen in einer einschließenden Gültigkeitsbereich deklariert, so versucht, diese aus:

#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> ();
}

Hier bin ich nur versucht, eine lokale Art im umgebenden Gültigkeitsbereich zu erstellen und innerhalb der Lambda-Funktion verwenden. Nicht nur, dass dies nicht kompiliert (mit Visual Studio 2010 Beta 2), aber es stürzt tatsächlich den Compiler mit einem C1001 internen Fehler.

Ich habe zwei Fehlerberichte eingereicht.

Wir werden sehen, wie es geht. :)


Update

Beide Fehler wurden als feste markiert:

  

Wir freuen uns über Ihr Feedback. Dieser Fehler wurde von uns schon einmal gesehen, und wir haben es in der nächsten Version behoben. Vielen Dank für das Produkt verwenden.

     

Danke,
  Ulzii Luvsanbat
  Windows-C ++ Team

So gibt wir gehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top