VS2010部分支持C++11。我在VS2010 RTM中编译了下面的代码。我不明白为什么对代码CLS()进行不同意义的分析。在“decltype( CLS() obj1;”)行中,CLS()表示类对象实体。但是在"CLS obj2( CLS() )“行中,CLS ()表示一个函数指针,它不带参数地重新运行CLS对象。行为被期待了吗?它在标准中被描述过吗?
struct CLS
{
int mi;
};
int _tmain(int argc, _TCHAR* argv[])
{
decltype(CLS()) obj1;
obj1.mi = 10;
CLS obj2(CLS());
obj2.mi = 10; // error C2228: left of '.mi' must have class/struct/union
return 0;
}更新2011年8月12日
按照C++11 7.1.6.2/1,括号中的预期字符串是表达式。编译器只需检查字符串是否可以解析为有效表达式。如果是,代码是格式良好的。因此,对于代码“decltype(CLS()obj1;”),"CLS()“被视为表示对象定义的有效表达式。
decltype-specifier:
decltype ( expression )更新1/3/2012
Potatoswatter解释了为什么"CLS obj2(CLS(CLS())“不是对象定义的声明。
任何可能被解释为表达式或声明的东西都是声明,不管它多么不寻常。CLS obj2( CLS() );声明一个函数,其参数类型CLS()是一个没有返回CLS参数的函数,其返回类型为CLS。
发布于 2012-01-01 20:18:53
正如其他人所说,这是最令人烦恼的问题。任何可能被解释为表达式或声明的东西都是声明,不管它多么不寻常。CLS obj2( CLS() );声明一个函数,其参数类型为CLS()是一个没有返回CLS的参数的函数,其返回类型为CLS。
例如,
CLS obj2( CLS() ); // forward declaration
CLS obj2( CLS fun() ) { // definition
return fun(); // use unusual functional argument
}
CLS foo() { // define a function to use as unusual argument
return CLS();
}
int main() {
CLS obj2( CLS() ); // still a forward declaration, even in this context!
CLS x = obj2( foo );
}解决方案是使用C++11的统一初始化。
CLS obj2{ CLS() };或者简单的
CLS obj2{};发布于 2011-12-07 04:39:39
是的吗?是的
它被称为"most vexing parse“。
CLS obj2(CLS()); // function forward declaration.
CLS obj2 = CLS(); // Creates object zero initialized.
CLS obj2; // Creates object default initialized.发布于 2011-12-07 19:29:19
在decltype的论点中,需要一个表达式。将CLS()解释为表达式的唯一方法是将其解析为CLS类型的默认构造对象。
然而,在CLS obj2(CLS()) ( BTW在C++03中的工作方式相同)中,有两个可能的解析:一个作为函数声明,另一个作为对象定义。作为函数声明,外括号形成一个参数列表,内容将通过提供类型和可选名称来指定参数(或它们的列表)。在该解析中,CLS()被解释为函数类型。
另一个有效的解析是作为对象的定义。当然,对于该解析,在括号中必须有一个表达式(或它们的列表),将CLS()解释为CLS类型的默认构造对象。
现在在C++中有一条规则,如果某物既可以被解析为声明,也可以被解析为定义,那么它将被解析为声明。也就是说,在这种情况下,将使用第一种解释。
当然,这就产生了一个问题,即为什么选择第一种解释,而我们显然希望在此作出第二种解释。答案是,否则它将破坏C的兼容性(在某些情况下甚至是我们的期望)。例如,查看以下行:
int f();现在您会同意,这声明了一个不带参数并返回int的函数,对吗?但是它也可以被解析为int类型的默认初始化变量的定义。由于上面提到的规则,它确实声明了一个返回int的函数。
在最好的情况下,总是给出预期结果的规则是复杂的,但很可能是不可能的。
注意,在C++03中,避免使用自动变量的一个简单方法是在定义前面加上auto:因为函数声明从来不以auto开头,这将迫使编译器将其解释为变量定义。由于auto的旧含义在C++11中被移除,这不再有效(对于非自动变量,它也从未起作用)。
https://stackoverflow.com/questions/8410433
复制相似问题