Можно ли использовать анонимный класс в качестве возвращаемых типов в C ++? - PullRequest
11 голосов
/ 06 ноября 2011

Есть ли способ использовать анонимные классы в C ++ в качестве возвращаемых типов?

Я подумал, что это может сработать:

struct Test {} * fun()
{
}

Но этот кусок кода не компилируется,сообщение об ошибке:

новые типы не могут быть определены в возвращаемом типе

На самом деле код не имеет никакого смысла, я просто хочу выяснить,анонимный класс может использоваться как тип возвращаемого значения в C ++.

Вот мой код:

#include <typeinfo>
#include <iterator>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>

using namespace std;

int main(int argc, char **argv)
{
    int mx = [] () -> struct { int x, y ; } { return { 99, 101 } ; } ().x ;
    return 0;
}

Я компилирую этот код с помощью g ++ xx.cpp -std = c ++ 0x, компиляторCompains:

expected primary-expression before '[' token.

Ответы [ 6 ]

6 голосов
/ 07 ноября 2011

Примечание. Эти фрагменты кода больше не работают в последних версиях g ++.Я скомпилировал их с версией 4.5.2, но версии 4.6.1 и 4.7.0 больше не принимают их.


Вы можете объявить анонимную структуру как тип возврата лямбда-функции в C ++ 11.Но это не красиво.Этот код присваивает значение 99 mx:

int mx = [] () -> struct { int x, y ; } { return { 99, 101 } ; } ().x ;

Выход идеона здесь: http://ideone.com/2rbfM

В ответ на запрос Ченга:

Функция лямбдаэто новая функция в C ++ 11.Это в основном анонимная функция.Вот более простой пример лямбда-функции, которая не принимает аргументов и возвращает int:

[] () -> int { return 99 ; }

. Вы можете присвоить это переменной (для этого нужно использовать auto):

auto f = [] () -> int { return 99 ; } ;

Теперь вы можете назвать это так:

int mx = f() ;

Или вы можете позвонить напрямую (именно так поступает мой код):

int mx = [] () -> int { return 99 ; } () ;

Мой код просто использует struct { int x, y ; } вместо int..x в конце - это обычный синтаксис члена struct, применяемый к возвращаемому значению функции.

Эта функция не так бесполезна, как может показаться.Вы можете вызывать функцию более одного раза, чтобы получить доступ к различным членам:

auto f = [] () -> struct {int x, y ; } { return { 99, 101 } ; } ;
cout << f().x << endl ;
cout << f().y << endl ;

Вам даже не нужно вызывать функцию дважды.Этот код выполняет в точности то, что запрашивал ОП:

auto f = [] () -> struct {int x, y ; } { return { 99, 101 } ; } () ;
cout << f.x << endl ;
cout << f.y << endl ;
5 голосов
/ 06 ноября 2011

Не они не могут.Как указано в сообщении об ошибке, из ИСО / МЭК 14882: 2011 8.3.5 / 9:

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

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

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

3 голосов
/ 06 ноября 2011
struct Test {} * a;
decltype(a) fun() {
  return a;
}

кстати, struct Test {} не является анонимной структурой.

2 голосов
/ 06 ноября 2011

Нет, вы не можете делать такие анонимные типы в C ++.

Однако вы можете использовать typedef для назначения анонимным типам новых имен.

typedef struct
{
    unsigned x;
    unsigned y;
} TPoint;
1 голос
/ 06 ноября 2011

Поскольку пост @ Чарльза в значительной степени отвечает на вопрос, прямо цитирующий спецификацию.

Теперь я думаю, почему анонимный тип не может быть возвращаемым типом функции, потому что предположим, что f возвращает анонимный тип, тогда что можно написать на вызывающем сайте?

?????  obj = f();

Что должно быть написано вместо ????? в приведенном выше коде?

0 голосов
/ 10 ноября 2017

Самое близкое, что вы можете получить к тому, что вы хотите, это в C ++ 14:

auto f() { 
    struct {
        int x, y;
    } ret{10,24};
    return ret;
}
int main() {
  printf("%i", f().x);
}

Структура является анонимной (ret - это имя переменной, а не имени типа) и возвращается.

Вы можете получить его, если нужно, с помощью

using my_struct = decltype(f());
my_struct another; another.x++;
...