有这段代码:
class SomeClass
{
public:
SomeClass(){}
SomeClass(SomeClass& b){}
SomeClass(SomeClass&b, SomeClass& c){}
};
int main()
{
SomeClass a;
SomeClass(); // works all right
//SomeClass(a); error: redeclaration of ‘SomeClass a’
SomeClass(a, a); // works all right
return 0;
}
可以声明具有0和2参数的SomeClass的匿名对象,但不能仅使用1个参数声明它。我假设写作
SomeClass(a);
与
相同SomeClass a;
如何使用一个参数创建匿名对象?
答案 0 :(得分:3)
您可以在自己的语句中构造一个临时对象,例如:
(SomeClass)a;
或
(SomeClass(a));
正如您所观察到的,需要使用括号来解决声明和表达式语句之间的歧义。
答案 1 :(得分:2)
您可以按以下方式创建该匿名对象:
(SomeClass(a));
这解决了歧义,因为它不能是a
的声明。
(SomeClass a); // Error: this can't be a declaration because of the parentheses
// but what else should it be?
答案 2 :(得分:2)
在这种情况下,大括号是多余的,这意味着
SomeClass(a); //declaration of a
完全等同于
SomeClass a; //declaration of a
再次等同于:
SomeClass((a))); //declaration of a
SomeClass(((a))); //declaration of a
SomeClass((((a)))); //declaration of a
SomeClass(((((a))))); //declaration of a
所有这些都声明了一个名为a
的变量,并输入SomeClass
。
答案 3 :(得分:1)
一般情况下,通过编写与您想编写的代码具有相同效果的代码来避免最令人烦恼的解析,但不能将其解析为声明。
通常,这是通过添加括号来完成的。
在这种情况下,(SomeClass(a));
会执行,或(void) SomeClass(a);
答案 4 :(得分:0)
你的假设是正确的。
您无法在上下文中创建具有单个构造函数参数的临时对象,其中同一语句可以是声明。语法使它变得模棱两可(或者,如果你所看到的行为没有被定义为优先的话, 会不明确。)
为什么不给对象命名呢?
SomeClass obj(a);
或者,如果您有理由希望立即销毁该对象(有时这很有用;例如boost::this_thread::interruption_point
,虽然不带参数),您仍然可以创建一个临时的但是消除歧义的语句:
(SomeClass(a)); // the parens prevent this from being a declarative statement
在某些情况下,您也可以使用C风格的演员阵容:
(SomeClass)a;
但是,希望您的SomeClass
构造函数实际上标记为explicit
,我们仍然不想使用C风格的强制转换。
这个问题在其他情境中不会出现,暂时可能会更有意义:
std::cout << SomeClass(a); // *can't* be a decl of a `SomeClass` called `a`