2010-10-31 14 views
5

acabo reescrito el siguiente código C89, que regresa de la función actual:regreso de una persona que llama lambda C++ 0x directamente

// make sure the inode isn't open 
{ 
    size_t i; 
    for (i = 0; i < ARRAY_LEN(g_cpfs->htab); ++i) 
    { 
     struct Handle const *const handle = &g_cpfs->htab[i]; 
     if (handle_valid(handle)) 
     { 
      if (handle->ino == (*inode)->ino) 
      { 
       log_info("Inode "INO_FMT" is still open, delaying removal.", 
         (*inode)->ino); 
       return true; 
      } 
     } 
    } 
} 

Con este C++ 0x STL/híbrida lambda:

std::for_each(g_cpfs->htab.begin(), g_cpfs->htab.end(), [inode](Handle const &handle) { 
    if (handle.valid()) { 
     if (handle.ino == inode->ino) { 
      log_info("Inode "INO_FMT" is still open, delaying removal.", inode->ino); 
      return true; 
     } 
    }}); 

que genera:

1> e: \ src \ cpfs4 \ libcpfs \ inode.cc (128): error C3499: un lambda que se ha especificado para tener un tipo de retorno void no puede volver av alue

No había considerado que el retorno en la lambda, en realidad no regrese de la persona que llama (nunca antes había visto una función de ámbito en C/C++). ¿Cómo puedo return true de la persona que llamó donde la función original lo habría hecho?

Respuesta

6

Usted no lo hace; std :: for_each no está estructurado para manejar un retorno anticipado. Se podría lanzar una excepción ...

O no utilizar un lambda:

for (auto const &handle : g_cpfs->htab) { 
    // code that was in lambda body 
} 
+0

Nota "gama basada en los bucles" (como el 0x draft los llama) son "foreach loops", que es lo que estabas tratando de obtener de std :: for_each. –

+0

La sintaxis foreach es precisamente lo que estaba buscando. –

+0

Sí, eliminé ese comentario nuevamente. Supuse que se refería a la sintaxis 'for_each'. :) – jalf

2

Uso std::find_if() en lugar de std::for_each():

if (std::find_if(g_cpfs->htab.begin(), g_cpfs->htab.end(), 
     [inode](Handle const &handle) { 
      if (handle.valid() && handle.ino == inode->ino) { 
       log_info("Inode "INO_FMT" is still open, delaying removal.", 
        inode->ino); 
       return true; 
      } 
      return false; 
     }) != g_cpfs->htab.end()) { 
    return true; 
} 
+0

Si bien find_if no funciona para corregir la impedancia de bucle, usarlo con if y los valores de retorno como ese parecen incorrectos. –

+0

@Roger, sí, también tuve que usar una sangría bastante extraña para que sea legible. Funciona, sin embargo, así que no sé si eso es realmente un problema ... –

+0

Se siente raro, pero esta es la mejor manera de hacerlo, dado que MSVC2010 no parece ser compatible con el rango basado en? –

Cuestiones relacionadas