Os typedefs da função local são visíveis dentro de C ++ 0x Lambdas?
-
22-09-2019 - |
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.)
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.