Pergunta

Eu encontrei um problema estranho. O código simplificado a seguir reproduz o problema no 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
}

o typedef Criei localmente na função não parece ser visível no Lambda. Se eu substituir o typedef Com o tipo real, ele funciona como esperado.

Aqui estão alguns outros casos de teste:

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

Não tenho G ++ disponível para testá -lo, agora. Esta é uma regra estranha em C ++ 0x, ou apenas um bug no compilador?

A partir dos resultados acima, estou inclinado para o bug. Embora o acidente seja definitivamente um bug.


Por enquanto, eu arquivei dois relatório de erros.

Todos os trechos de código acima devem compilar. O erro tem a ver com o uso da resolução do escopo nos escopos definidos localmente. (Avistado por DVIDE.)

E o bug do acidente tem a ver com ... quem sabe. :)


Atualizar

De acordo com relatório de erros, ambos foram corrigidos para o próximo lançamento do Visual Studio 2010. (Embora esse não pareça ser o caso; talvez vs11.)

Foi útil?

Solução

De N3000, 5.1.2/6,

A estatura composta do Lambda-Expression gera o corpo da função (8.4) do operador de chamada de função, mas para fins de pesquisa de nomes (3.4),… a estatura composta é considerada no contexto da expressão lambda.

Não é de surpreender que o tipo local deve ser visível.

Outras dicas

As enumes-funções locais também não podem ser detectadas por lambdas.

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

Erro C3493: 'a' não pode ser capturado implicitamente porque nenhum modo de captura padrão foi especificado

A seguir, é apresentada uma subida e problemática-maybe.

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

Isso não é realmente uma resposta para sua pergunta, mas apenas explorando o problema ainda mais. Eu queria saber se o compilador tem problemas para lidar com tipos declarado em um escopo fechado, então tentei o seguinte:

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

Aqui, estou apenas tentando criar um tipo local no escopo anexo e usá -lo da função Lambda. Isso não apenas não compila (com o Visual Studio 2010, beta 2), mas também trava o compilador com um erro interno C1001.

Eu arquivei dois relatórios de bug.

Vamos ver como vai. :)


Atualizar

Ambos os bugs foram marcados como corrigidos:

Agradecemos seu feedback. Esse bug já foi visto por nós antes e nós o corrigimos na próxima versão. Obrigado por usar o produto.

Obrigado,
Ulzii luvsanbat
Equipe Windows C ++

Então lá vamos nós.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top