Может ли анонимный класс использоваться в качестве возвращаемых типов в С++?
Можно ли использовать анонимные классы в С++ в качестве возвращаемых типов?
Я googled, что это может работать:
struct Test {} * fun()
{
}
Но эта часть кода не компилируется, сообщение об ошибке:
новые типы не могут быть определены в обратном типе
На самом деле код не имеет никакого смысла, я просто хочу выяснить, может ли анонимный класс использоваться в качестве возвращаемого типа в С++.
Вот мой код:
#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 = С++ 0x, компилятор компилирует:
expected primary-expression before '[' token.
Ответы
Ответ 1
Примечание. Эти фрагменты кода больше не работают в последних версиях g++. Я скомпилировал их с версией 4.5.2, но версии 4.6.1 и 4.7.0 больше не принимают их.
Вы можете объявить анонимную структуру как возвращаемый тип лямбда-функции в С++ 11. Но это некрасиво. Этот код присваивает значение от 99 до mx
:
int mx = [] () -> struct { int x, y ; } { return { 99, 101 } ; } ().x ;
Выход ideone находится здесь: http://ideone.com/2rbfM
В ответ на запрос cheng:
Лямбда-функция - это новая функция в С++ 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 ;
Вам даже не нужно дважды вызывать функцию. Этот код делает именно то, что запросил OP:
auto f = [] () -> struct {int x, y ; } { return { 99, 101 } ; } () ;
cout << f.x << endl ;
cout << f.y << endl ;
Ответ 2
Не могут. Как указано в сообщении об ошибке, из ISO/IEC 14882: 2011 8.3.5/9:
Типы не должны определяться в обратном порядке или в параметрах. Тип параметра или тип возвращаемого значения для определения функции не должен быть неполным типом класса (возможно, с квалификацией cv), если определение функции не вложено в спецификацию элемента для этого класса (включая определения в вложенных классах, определенных в классе).
И вы, конечно, не можете назвать существующий анонимный тип как возвращаемый тип в объявлении функции, так как анонимный класс не имеет имени.
Хотя вы можете создать typedef
для неназванного класса и использовать его как возвращаемый тип, поскольку имя typedef становится именем типа класса для целей привязки, класс уже не является анонимным.
Ответ 3
struct Test {} * a;
decltype(a) fun() {
return a;
}
btw, struct Test {}
не является анонимной структурой.
Ответ 4
Нет, вы не можете делать подобные анонимные типы на С++.
Однако вы могли бы использовать typedef
для присвоения анонимным типам новых имен.
typedef struct
{
unsigned x;
unsigned y;
} TPoint;
Ответ 5
Как @Charles публикует довольно много ответов на вопрос, непосредственно цитирующий из спецификации.
Теперь я думаю, почему анонимный тип не может быть возвращаемым типом функции, потому что предположим, что f
возвращает анонимный тип, то что бы написать на вызывающем сайте?
????? obj = f();
Что должно быть написано вместо ?????
в приведенном выше коде?
Ответ 6
Ближе всего вы можете дойти до того, чего хотите, в С++ 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++;