Почему этот функтор («лямбда») выдает странное предупреждение? - PullRequest
0 голосов
/ 25 августа 2011

Когда я компилирую и запускаю это с Visual C ++ 2010:

#include <iostream>

int main() {
    int subtrahend = 5;

    struct Subtractor {
        int &subtrahend;
        int operator()(int minuend) { return minuend - subtrahend; }
    } subtractor5 = { subtrahend };

    std::cout << subtractor5(47);
}

Я получил правильный ответ, 42.

Тем не менее, компилятор жалуется, что это невозможно:

Temp.cpp (9): предупреждение C4510: main::Subtractor: Конструктор по умолчанию не может быть создан
Temp.cpp (6): см. Объявление main::Subtractor

Temp.cpp (9): предупреждение C4512: main::Subtractor: Оператор назначения не может быть сгенерирован
Temp.cpp (6): см. Объявление main::Subtractor

Temp.cpp (9): предупреждение C4610: struct main::Subtractor никогда не может быть создан - требуется определенный пользователем конструктор

Что происходит?

Ответы [ 4 ]

4 голосов
/ 25 августа 2011

Первые два предупреждения просто сообщают вам, что неявно объявленные функции-члены не могут быть сгенерированы из-за присутствия элемента справочных данных.

Третье предупреждение: ошибка компилятора Visual C ++ .

Все три предупреждения могут быть проигнорированы без каких-либо побочных эффектов, хотя вы легко можете убрать все три предупреждения, указав вместо этого элемент ссылочных данных (члены ссылочных данных почти никогда не стоят проблем).

1 голос
/ 25 августа 2011

Первое предупреждение - сообщить вам, что ссылочное значение не может быть построено по умолчанию (ссылки гарантированно указывают на какое-то значение).Переключите вычитаемое число на обычное целое число, и проблема исчезнет.

Я почти уверен, что второе предупреждение аналогичного характера.что-то вроде boost :: function или аналогичной реализации (std :: tr1 :: function?) вместо написания этого кода вручную)

0 голосов
/ 25 августа 2011

Пользовательский конструктор является обязательным в следующих случаях:

  • Инициализация постоянных элементов данных (const int c_member;).
  • Инициализация элементов справочных данных (int & r_member;)
  • Наличие элемента данных, тип которого не имеет конструктора по умолчанию.Например:

    class NoDefCtor {public: NoDefCtor (int);};

    class ContainThat {NoDefCtor no_ctor_member;};

  • Наследование от базового класса, где базовый класс не имеет конструктора по умолчанию.Почти так же, как указано выше (NoDefCtor).

0 голосов
/ 25 августа 2011

Это потому, что переменная subtractor5 является безымянной структурой. Если вы хотите, чтобы ошибки исчезли, присвойте структуре, используемой для subtractor5.

Например:

struct subtractor {
 :
} subtractor5 = { subtrahend };

К сожалению, я недостаточно знаю язык C ++, чтобы понять, почему он работает, но я знаю, почему происходит предупреждение.

...