C ++中的以下代码compiles
struct foo
{
int a, b;
};
struct foo foo()
{
struct foo a;
return a;
}
int main(void) {
foo();
return 0;
}
因为它编译了我然后继续尝试声明类型为foo
的对象。有办法吗?似乎不可能做到:
foo a; // error: expected ‘;’ before ‘a’
foo a{}; // error: expected ‘;’ before ‘a’
foo a(); // most vexing parse would kick in any way
答案 0 :(得分:7)
是的,我们可以通过转到draft C++ standard部分3.3.10
名称隐藏段落 2 来看到这一点( >强调我的):
类名(9.1)或枚举名(7.2)可以通过在同一范围内声明的变量,数据成员,函数或枚举器的名称隐藏。 如果类或枚举名称和变量,数据成员,函数或枚举器在同一作用域(按任何顺序)中声明具有相同名称,则类或枚举名称将隐藏在变量,数据成员,功能或枚举器名称可见。
在这种情况下,在声明中使用struct
可以解决您的问题:
struct foo a;
答案 1 :(得分:1)
通常不好意思做这样的事情。我将它命名为foo_s或其他任何区别于函数。除此之外,还没有真正的方法。
在C中这是可能的,因为它需要
struct foo
而不仅仅是
FOO
作为类型名称(除非是typedef' d)
答案 2 :(得分:1)
就像在C中一样,使用:
struct foo a;
您甚至可以像这样初始化它:
struct foo a{};
struct foo a = {0};
解决方法是使用typedef,从而避免任何歧义和其他困难:
typedef struct foo s_foo;
答案 3 :(得分:1)
是的,你可以,但这是一个非常糟糕的模式。
struct foo
{
};
foo foo(foo& f)
{
return f;
}
int main()
{
struct foo f;
foo(f);
return 0;
}
请参阅livedemo:http://ideone.com/kRK19f
当我们想要获得该类型时,诀窍是指定struct foo
。请注意,在您创建此歧义之前,实际上没有必要继续说struct
,这不是C(如行foo foo(foo& f)
中所示)。
大多数开发人员选择驼峰套管图案,例如他们使用大写字母来区分类型名称和函数名称的小写字母:
struct Foo
{
};
Foo foo(); // no ambiguity.
回到微软的鼎盛时期,许多Windows开发人员习惯于为结构/类定义添加前缀,如果你愿意的话,定义一类东西,用大写字母C
struct CFoo
{
};
现在,即使你想为你的函数名使用大写的第一个字母,也没有歧义。
答案 4 :(得分:0)
来自The.C ++。Programming.Language.Special.Edition $ A.8:
为了保持C兼容性,可以在同一个名称中声明一个类和一个同名的非类 范围(5.7美元)。例如:
struct stat { /* ... */ };
int stat(char * name, struct stat * buf);
在这种情况下,普通名称(stat)是非类的名称。必须使用该类 一个类密钥前缀。