2012-03-08 15 views
48

Gdy próbuję i skompilować ten kod (VS2010) otrzymuję następujący błąd: error C3499: a lambda that has been specified to have a void return type cannot return a valueExplicit Typ Powrót Lambda

void DataFile::removeComments() 
{ 
    string::const_iterator start, end; 
    boost::regex expression("^\\s?#"); 
    boost::match_results<std::string::const_iterator> what; 
    boost::match_flag_type flags = boost::match_default; 
    // Look for lines that either start with a hash (#) 
    // or have nothing but white-space preceeding the hash symbol 
    remove_if(rawLines.begin(), rawLines.end(), [&expression, &start, &end, &what, &flags](const string& line) 
    { 
    start = line.begin(); 
    end = line.end(); 
    bool temp = boost::regex_search(start, end, what, expression, flags); 
    return temp; 
    }); 
} 

Jak ja określić, że lambda ma 'void' typ zwrotny. Ponadto, w jaki sposób określić, że lambda ma typ powrotu "bool"?

UPDATE

Poniższe kompiluje. Czy ktoś może mi powiedzieć, dlaczego to się kompiluje, a drugi nie?

void DataFile::removeComments() 
{ 
    boost::regex expression("^(\\s+)?#"); 
    boost::match_results<std::string::const_iterator> what; 
    boost::match_flag_type flags = boost::match_default; 
    // Look for lines that either start with a hash (#) 
    // or have nothing but white-space preceeding the hash symbol 
    rawLines.erase(remove_if(rawLines.begin(), rawLines.end(), [&expression, &what, &flags](const string& line) 
    { return boost::regex_search(line.begin(), line.end(), what, expression, flags); })); 
} 
+4

można jednoznacznie określić jej '->', np '[&] (double d) -> double {// ...' – Flexo

+2

Radzę ci tylko domyślnie przechwycić potrzebne zmienne (tylko '[&] ...'), ponieważ to co masz obecnie jest niepotrzebnie gadatliwy. – Xeo

+0

@Xeo czy możesz mi powiedzieć, dlaczego jest to skrót? Potrzebuję czegoś, ekspresji i flag w lambda i to właśnie złapałem. Co mógłbym wyciąć? – Ryan

Odpowiedz

114

można jednoznacznie określić typ zwracanej lambda za pomocą -> Type po liście argumentów:

[]() -> Type { } 

Jeśli jednak lambda ma jedno oświadczenie i że oświadczenie to return (i to zwraca wyrażenie), kompilator może wywnioskować typ zwracany z typu zwracanego wyrażenia. Masz wiele instrukcji w swoim lambda, więc nie wywnioskuje on typu.

+3

kompilator może to zrobić, ale standard zabrania mu tego. –

+7

-1: To nie jest błąd kompilatora. Norma jest bardzo jasna: punkt 5.1.2, ust. 4 określa, w jaki sposób dokonuje się odliczenia i na jakich warunkach jest to dokonywane. –

+2

Naprawiono @NicolBolas. –

9

Rodzaj powrót lambda można wywnioskować, ale tylko gdy istnieje dokładnie jedna instrukcja, a to stwierdzenie jest return oświadczenie, że zwraca wyrażenie (an lista inicjator nie jest wyrazem, na przykład). Jeśli masz multi-instrukcję lambda, to typ powrotu jest nieważny.

Dlatego należy to zrobić:

remove_if(rawLines.begin(), rawLines.end(), [&expression, &start, &end, &what, &flags](const string& line) -> bool 
    { 
    start = line.begin(); 
    end = line.end(); 
    bool temp = boost::regex_search(start, end, what, expression, flags); 
    return temp; 
    }) 

ale naprawdę, drugi wyraz jest dużo bardziej czytelny.

+0

Dobry przykład; nitpick: Czy twoja funkcja nie ma nazwy ');' na końcu? – kevinarpe

2

Można mieć więcej niż jedną instrukcję kiedy jeszcze powrócić:

[]() -> your_type {return (
     your_statement, 
     even_more_statement = just_add_comma, 
     return_value);} 

http://www.cplusplus.com/doc/tutorial/operators/#comma

+2

przecinek to odrażający operator. to dezorientuje ludzi, którzy nie są świadomi jego istnienia lub poziomu pierwszeństwa. nigdy nie ma ważnego zastosowania ani imo. zawsze można tego uniknąć dzięki większej liczbie funkcji lub lepiej zorganizowanemu kodowi. – jheriko

+0

@jheriko zgadzam się, istnienie mojej odpowiedzi jest tylko dla tych, którzy naprawdę chcą niezależnego rozwiązania One-liner XD (to wciąż jedna linia, prawda?). Przecinek naprawdę nie jest zauważalny i nikt nigdy nie umieściłby całej głównej metody w tej formie. – Valen

+1

Oczywiście, z pewnością dajesz poprawną odpowiedź, po prostu nie jestem fanem kiedykolwiek robię cokolwiek, aby zachęcić lub nawet zademonstrować złą praktykę. gdy ludzie dowiedzą się, że przecinek jest operatorem, to odliczanie, dopóki nie zaczną go nadużywać i dłużej, dopóki nie nauczą się lepiej. :) – jheriko

Powiązane problemy