2010-07-09 25 views
6

tengo el siguiente códigoexpresión lambda (MSVC++ vs g ++)

#include <algorithm> 
#include <iostream> 
#include <vector> 
#include <functional> 


int main() 
{ 
    typedef std::vector<int> Vector; 
    int sum=0; 
    Vector v; 
    for(int i=1;i<=10;++i) 
    v.push_back(i); 

    std::tr1::function<double()> l=[&]()->double{ 

    std::for_each(v.begin(),v.end(),[&](int n){sum += n; //Error Here in MSVC++}); 
    return sum; 
    }; 

    std::cout<<l(); 
    std::cin.get(); 
} 

El código anterior produce un error en MSVC++ 10 mientras que compila bien con g++ 4.5. El error producido es 1 IntelliSense: invalid reference to an outer-scope local variable in a lambda body c:\users\super user\documents\visual studio 2010\projects\lambda\lambda.cpp 19 46 lambda

Así que, ¿hay alguna otra manera de acceder al exterior ámbito de las variables-sum sin crear explícitamente una nueva variable dentro de la expresión lambda local (dentro std::for_each)?

En g++ 4.5 el código compila bien. ¿El estándar (proyecto N3000) decir nada al respecto? (No tengo una copia de C++ - 0x (1x) estándar en la actualidad)

+1

doees VS10 tienen algunos errores conocidos relacionados con el ámbito de aplicación de captura de lambda, som más probable GCC es correcto en este caso. – jalf

+0

acaba de descargar un borrador estándar reciente, en busca de "estándar de C++" en Google le da un enlace para ello. Es una experiencia de aprendizaje interesante echarle un vistazo :) –

+2

Tenga en cuenta que el último borrador es el FCD, N3092, que puede [descargar del sitio web del WG21] (http://www.open-std.org/jtc1/ sc22/wg21/docs/papers/2010/n3092.pdf) (** advertencia: 10.5MB PDF **). –

Respuesta

15

¿De verdad ha intentado compilar el código en la pregunta? Visual C++ 2010 acepta el código, tal como está (obviamente, con el comentario eliminado) y compila el código correctamente sin error.

El "error" que está viendo no es un error de compilación, sino un error de IntelliSense. La comprobación de errores de IntelliSense da como resultado muchos falsos positivos (he informado de varios errores en Microsoft Connect en los últimos meses); en este caso, IntelliSense está diciendo incorrectamente que esto es un error cuando no lo es.

Tiene dos opciones: puede ignorar los falsos positivos de IntelliSense o puede deshabilitar la comprobación de errores de IntelliSense (haga clic con el botón derecho en la ventana Lista de errores y desmarque "Mostrar errores de IntelliSense").

De cualquier forma, estos errores de IntelliSense de ninguna manera impiden que la compilación tenga éxito.

0

creo que es posible que tenga que declarar explícitamente el cierre sobre sum, de este modo:

std::for_each(v.begin(),v.end(),[&sum](int n){sum += n;}); 

en general, se supone que se le permita capturar implícitamente las variables en el ámbito local, pero sólo el tiempo que se garantiza la lambda para ejecutar en el mismo ámbito. Posiblemente porque estás asignando tu lambda a una función var y ejecutándola más tarde (en lugar de solo ejecutarla directamente), MSVC no es lo suficientemente inteligente como para entender que esa condición se cumple, después de todo, podrías pasar l y ejecutarlo en algún otro ámbito, por lo que requiere una declaración de captura explícita.

1

Independientemente de si VC es incorrecto o correcto, es un mal estilo que haya declarado su suma fuera de su lambda (externa). Como devuelve el valor de suma, no es necesario cambiar el valor de una variable externa dentro del ciclo. En su lugar, debe tener:

int sum = 0; 
std::for_each(v.begin(),v.end(),[&](int n){sum += n;}); 
return sum; 

Podría ser que las lambdas anidadas también confunden VC. Diría que es excesivo tener lambdas anidados, y hace que el código sea menos legible.

0

Creo que el único problema que tiene es con esa ola roja del tamaño de una hormiga .... SINCE Microsoft había lanzado el compilador antes y pronto el organismo de normas cambió la regla para buscar el nombre ... así que intellisense no está hasta fecha ........

INTÉNTESE DE ACUERDO CON ESTA IDEA ..... BEBÉ ...

#include <algorithm> 
#include <iostream> 
#include <vector> 
#include <functional> 


int main() 
{ 
    typedef std::vector<int> Vector; 
    int sum=0; 
    Vector v; 
    for(int i=1;i<=10;++i) 
    v.push_back(i); 

    std::tr1::function<double()> l=[&]()->double{ 
     int *y; y=&sum; 
     std::for_each(v.begin(),v.end(),[&](int n){*y += n; }); 
    return sum; 
    }; 

    std::cout<<l(); 
    std::cin.get(); 
} 
+0

Ya recibí la respuesta y resolví mi problema. Por cierto, no hay necesidad de usar un raw_pointer aquí. Incluso una referencia a la suma habría resuelto el problema. Por cierto, puede desactivar esa opción 'show intellisense errors'. Espero que lo sepas. Sin embargo, el código es técnicamente correcto, así que lo mencioné aquí también: http://stackoverflow.com/questions/3221812/sum-of-elements-in-a-vector/3221813#3221813 –

+0

si su código era técnicamente correcto I no encuentro una razón para publicar errores tan tontos aquí en un foro ... Creo que si eres un buen programador no disparas un pan en público, por lo que todos los perros correrán después de eso, (una analogía para los miembros de este foro) ... intentan discutir cosas en lugar de ayudar ........ – perilbrain

+2

Este no es un foro de discusión sino un sitio de preguntas y respuestas. Inicialmente, no estaba seguro de la validez del código en MSVC++, pero después de leer la respuesta de James me di cuenta de que el error era simplemente un error intellisense y mi código era perfectamente válido. Soy libre de hacer lo que quiera. Si no le gusta mi pregunta (o respuesta), no publique sus respuestas/comentarios. No es necesario en absoluto. "intentan discutir cosas en lugar de ayudar" Las preguntas que son subjetivas y aumentativas se cierran inmediatamente. Parece que eres nuevo en este sitio. –