2011-09-02 5 views
6

El siguiente ejemplo demuestra el problema que encontramos en VC++ 2010:¿Qué son las reglas de búsqueda cuando se llama a la función de lambda?

class Foo 
{ 
    template<class T> 
    static T foo(T t) { return t; } 

public: 
    void test() 
    { 
     auto lambda = []() { return foo(1); }; // call to Foo::foo<int> 
     lambda(); 
    } 
}; 

VC++ produce: error C3861: 'foo': identificador no encontrado

Si califico la llamada a foo: Foo::foo(1); entonces este ejemplo compila con una advertencia: advertencia C4573: el uso de 'Foo::foo' requiere que el compilador capture 'this' pero el modo de captura predeterminado actual no lo permite

¿Qué dice la norma sobre este caso? ¿Debería encontrar un nombre no calificado? ¿El nombre calificado requiere capturar this?

+0

Hm, eso es raro. Es estático, por lo que no debería requerir 'esto'. Sospecho que es un error del compilador y que no encontrarlo es un efecto secundario del compilador que cree que necesita 'esto' para usarlo. –

+0

Esto también ocurre con g ++, por lo que no parece un error. Si lo cambia a [&]() en lugar de [](), entonces compila bien, pero eso se debe a que toma esto por referencia. – DrYap

+0

Habiendo dicho eso [otro hilo] (http://stackoverflow.com/questions/4940259/c0x-lambdas-require-capturing-this-to-call-static-member-function) dice que es un error. – DrYap

Respuesta

4

Microsoft ha estado observando este problema en varios casos. Ver:

Scope Resolution with lambdas interferes with namespace and type resolution

Template resolution in lambdas

Como has encontrado a cabo, la resolución explícita que permite encontrar el nombre. Hay una advertencia adicional sobre esto que también es un error del compilador (la resolución del nombre no requiere acceso a esto, aunque puedo ver cómo una implementación del compilador podría requerirlo), aunque es un error por separado. Microsoft ha confirmado que se trata de un error y aparentemente ha preparado una solución para la próxima versión.

2

Lo siguiente compila bien. Me parece que esto solo debe ser un error VS con plantillas.

struct Foo { 
    static void foo() {} 
    void bar() { 
     auto f = []() { foo(); }; 
     f(); 
    } 
}; 
+0

¿Qué compilador probaste? Parece que el resultado varía según el compilador, por lo que es importante conocer el comportamiento estándar de conformidad. –

+0

@Gene: VC++ 2010 implementó lambdas pre [N2927] (http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n2927.pdf), por lo que es ** no * * conforme a la redacción de FDIS. – ildjarn

Cuestiones relacionadas