Can anonymous class be used as return types in C++?

风格不统一 提交于 2019-12-03 11:37:54
TonyK

Notice: These code snippets no longer work in the latest versions of g++. I compiled them with version 4.5.2, but versions 4.6.1 and 4.7.0 no longer accept them.


You can declare an anonymous struct as the return type of a lambda function in C++11. But it's not pretty. This code assigns the value 99 to mx:

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

The ideone output is here: http://ideone.com/2rbfM

In response to cheng's request:

The lambda function is a new feature in C++11. It's basically an anonymous function. Here is a simpler example of a lambda function, that takes no arguments and returns an int:

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

You can assign this to a variable (you have to use auto to do this):

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

Now you can call it like this:

int mx = f() ;

Or you can call it directly (which is what my code does):

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

My code just uses struct { int x, y ; } in place of int. The .x at the end is the normal struct member syntax applied to the function's return value.

This feature is not as useless as it might appear. You can call the function more than once, to access different members:

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

You don't even have to call the function twice. This code does exactly what the OP asked for:

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

Not they can't. As indicated in the error message, from ISO/IEC 14882:2011 8.3.5/9:

Types shall not be defined in return or parameter types. The type of a parameter or the return type for a function definition shall not be an incomplete class type (possibly cv-qualified) unless the function definition is nested within the member-specification for that class (including definitions in nested classes defined within the class).

And you can't, of course, name an existing anonymous type as the return type in a function declaration as an anonymous class has no name.

Although you can create a typedef for an unnamed class and use that as a return type, as the typedef name becomes the name of the class type for linkage purposes the class isn't really anonymous any more.

struct Test {} * a;
decltype(a) fun() {
  return a;
}

btw, struct Test {} is not an anonymous struct.

No, you can not do anonymous types like that in C++.

You could however, use typedef to assign anonymous types new names.

typedef struct
{
    unsigned x;
    unsigned y;
} TPoint;

As @Charles's post pretty much answers the question directly quoting from the spec.

Now, I think why anonymous type cannot be the return type of a function, is because suppose f returns an anonymous type, then what would one write at the calling site?

?????  obj = f();

What should be written in place of ????? in the above code?

The closest you can get to what you want is this, in C++14:

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

The struct is anonymous (ret is a variable name, not a type name), and is returned.

You can still get it if needed with

using my_struct = decltype(f());
my_struct another; another.x++;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!