Предупреждение компилятора: лямбда-тип возврата не может быть выведен - PullRequest
4 голосов
/ 21 декабря 2011

Рассмотрим этот пример:

#include <algorithm>
#include <iostream>

int main()
{
    std::string str = "abcde4fghijk4l5mnopqrs6t8uvwxyz";
    std::string str2;

    std::remove_copy_if(str.begin(), str.end(),
        std::back_inserter(str2),
        [](char& c) {
            if (std::isdigit(c))
                return true;      // <----- warning here
            else
                return false;
        }
    );

    std::cout << str2 << '\n';
}

В GCC 4.6.1 это прекрасно компилирует и печатает ожидаемый вывод (алфавит), но я получаю предупреждение, говорящее "лямбда-тип возврата может быть выведен, только когда оператор return является единственным оператором в теле функции" .

Теперь я знаю, как избавиться от предупреждения (используя конечный тип возврата или просто сказать return isdigit(c);), но мне любопытно, так как компилятор не предупреждает ни за что (или так должно быть): что может пойти не так в коде, как это? Стандарт говорит что-нибудь об этом?

Ответы [ 2 ]

5 голосов
/ 21 декабря 2011

Как говорит @ildjarn в своем комментарии, ваш код просто некорректен в соответствии со стандартом.

§5.1.2 [expr.prim.lambda] p4

[...] Если a Лямбда-выражение не включает тип трейлинг-возврата , как если бы тип трейлинг-возврата обозначает следующий тип:

  • если составной оператор имеет форму
    { атрибут-спецификатор-секв опт return выражение ;}
    тип возвращаемого выражения после преобразования lvalue-в-значение (4.1), преобразования массива в указатель (4.2) и преобразования функции в указатель (4.3);
  • в противном случае, void.

[...]

Вот и все, в основном, если код внутри фигурных скобок (называемый compund-Statement * 1039)* в стандарте) - это не что иное, как return some_expr;, в стандарте говорится, что тип возвращаемого значения не выводится, и вы получаете void тип возвращаемого значения.

3 голосов
/ 02 января 2015

Стоит отметить, что эта проблема была исправлена ​​в C ++ 14. Язык теперь правильно выводит тип возвращаемого значения, как ожидалось в OP. Из проекта стандарта [7.1.6.4.11]:

Если требуется тип сущности с неопределенным типом заполнителя чтобы определить тип выражения, программа плохо сформирована. Однако после того, как оператор возврата был замечен в функции, тип возврата, выведенный из этого оператора, может использоваться в остальной части функция, в том числе в других операторах возврата. [Пример:

auto n = n; // error, n’s type is unknown
auto f();
void g() { &f; } // error, f’s return type is unknown
auto sum(int i) {
if (i == 1)
    return i; // sum’s return type is int
else
    return sum(i-1)+i; // OK, sum’s return type has been deduced
}

- конец примера]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...