Почему я не могу объявить переменную структуры внутри лямбды в c ++ 0x? - PullRequest
3 голосов
/ 24 августа 2011

Вот код.

#include<struct.h>
#include<iostream>
#include<functional>
using namespace std;

void LambdaTest(const function <struct dummy (void)>& f)
    {
    struct dummy test = f();
    cout<<test.a<<endl;
    }

int main()
    {
    int val = 5;
    struct dummy dum;

    auto func = [val](void) -> struct dummy
                        {
                        dummy temp;
                        temp.a = val;
                        return temp;
                        };

    LambdaTest(func);
    return 0;
    }

Файл struct.h очень прост.

struct dummy
    {
    int a;
    };

GCC жалуется, что

lambda_struct.cpp: 19: 38: ошибка: поле «temp» имеет неполный тип

Это разрешено? Если да, то как мне это исправить? Если нет, то почему бы и нет?

EDIT:

Ошибка типа возврата в коде (обнаруженная другими) теперь исправлена.

РЕШЕНИЕ:

Проблема состоит в том, что стандарт C ++ 0x позволяет определять новую структуру (и, вероятно, тоже класс) в типе возврата самого лямбда-определения. Поэтому, если ключевое слово struct присутствует в возвращаемом типе, компилятор подумает, что это новый тип, и начнет жаловаться.

Фиксированный код

#include<struct.h>
#include<iostream>
#include<functional>
using namespace std;

void LambdaTest(const function <struct dummy (void)>& f)
    {
    struct dummy test = f();
    cout<<test.a<<endl;
    }

int main()
    {
    int val = 5;
    struct dummy dum;

    auto func = [val](void) -> dummy
                        {
                        dummy temp;
                        temp.a = val;
                        return temp;
                        };

    LambdaTest(func);
    return 0;
    }

Ответы [ 3 ]

7 голосов
/ 24 августа 2011

Проблема в том, что GCC неправильно думает, что вы объявляете новый тип структуры в конце возврата, и он объявляет поле неполного типа того же типа, что GCC считает, что вы объявляете.

Также жалуется, что

ошибка: «temp» не называет тип

в строке с присваиванием, поскольку оно ожидает объявления члена, а не оператора.

Изменение на:

auto func = [val](void) -> dummy
                        {
                            struct dummy temp;
                            temp.a = val;
                            return temp;
                        };

Будет работать.

Кроме того, помните, что не возвращая значение из функции, возможно, вы попадете в сферу неопределенного поведения.

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

В C ++, в отличие от C, структуры не помещаются в отдельное пространство имен, поэтому вам не нужно использовать ключевое слово struct в каждом объявлении.Также в вашем коде есть ошибка, лямбда должна вернуть экземпляр типа dummy.Следующие компиляции и запускаются как ожидалось

#include<iostream>
#include<functional>
using namespace std;

struct dummy
    {
    int a;
    };

void LambdaTest(const function <dummy (void)>& f)
    {
    dummy test = f();
    cout<<test.a<<endl;
    }

int main()
    {
    int val = 5;
    dummy dum;

    auto func = [val](void) -> dummy
                        {
                        dummy temp;
                        temp.a = val;
                        return temp; // return the temp struct
                        };

    LambdaTest(func);
    return 0;
    }

Вывод:

5

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

Что произойдет, если вы уберете часть struct и просто определите переменную как обычно?Вы знаете, просто:

dummy temp;

Кроме того, попробуйте избавиться от другого лишнего struct в возвращаемом лямбда-значении.Кстати говоря, вам нужно вернуть temp для его компиляции.

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