似乎您可以通过以下方式返回未命名的struct
:
auto foo() {
struct {
int bar;
int square() {
return bar * bar;
}
} a { 7 };
return a;
}
在没有冗余变量名a
的情况下是否仍然可以匿名执行此操作?
答案 0 :(得分:5)
对于初学者,C ++没有定义匿名结构。我认为您的意思是未命名的结构。
根据C ++标准,return语句的定义类似于(8.6 Jump语句)
return expr-or-braced-init-listopt ;
因此,您不得在return语句中使用声明。如果是这样,则需要初步声明将返回的结构类型的对象。
答案 1 :(得分:5)
不,这是不可能的。
您可以获得的最接近的结果是使用功能样式的强制转换创建临时文件,并使用C99样式的范围初始化器。 GCC允许在C ++模式下将此作为扩展:
#include <iostream>
#include <string>
auto foo() {
return (struct {
int bar;
int square() {
return bar * bar;
}
}) { 7 };
}
…但是这不能移植(并且会发出警告)。
没有括号7
的情况下,扩展名不会被触发,您将返回到标准代码it is illegal to define a type in a cast。
为您的类型命名并为对象命名,而不是编写晦涩的代码。您的读者将感谢您。
答案 2 :(得分:3)
我不知道此练习的目的是什么,所以这里给出的答案是 technically 满足您的要求:
auto helper()
{
struct {
int x;
} a {0};
return a;
}
decltype(helper()) foo()
{
return {8};
}
该结构未命名。
foo
不返回命名变量。
这当然是很荒谬的-只是命名结构而不是这个decltype
愚蠢的人。
答案 3 :(得分:2)
都不是
struct {/*...*/} foo() { // Illegal
return {/*...*/};
}
auto foo() {
return struct { /*...*/ } { /*...*/ }; // Illegal
}
template <typename T = struct { /*...*/ }> // Illegal
T foo() {
return { /*...*/ };
}
是合法的。
至少必须具有命名类型或命名实例。
Lambda不允许两者都包含,但您只能捕获并定义其operator()
:
auto foo() {
return [/*...*/](/*...*/) { /*...*/ }; // Legal
}
答案 4 :(得分:0)
返回匿名结构
在C ++中没有匿名结构这样的东西。这足以使其成为不可能。
有一种从函数返回匿名类型的对象的有限方法:返回一个lambda。
auto make_square_function() {
return [bar = 7]() {
return bar * bar;
};
}
尽管如此,Lambda的限制比普通类要多得多。成员(捕获)是封装的,不能从lambda外部进行命名,除了函数调用重载以外,没有成员函数。
在没有冗余变量名
a
的情况下是否仍然可以做到这一点
仅当您为课程命名时:
struct Squarer {
int bar;
int square() {
return bar * bar;
}
};
auto foo() {
return Squarer{7};
}
只能通过定义变量来返回未命名类的实例。
答案 5 :(得分:-1)
否,因为您需要返回对象的实例,在这种情况下为a。
返回的对象必须存在于内存中的某个位置,您不能只返回类定义。
在您的示例中,您没有返回匿名结构,但返回了该结构的实例。
答案 6 :(得分:-1)
另一个有趣的功能是定义另一个函数的解决方案(从Max Langhof的答案中汲取灵感)
auto foo ()
{
return []{ struct{int bar;} a {7}; return a; }();
}