我面临一个非常令人费解的问题。我正在尝试使用变量作为参数构造一个对象。
请看一下这段代码:
#include <iostream>
class A {
public:
A() : val(0) {};
A(int v) : val(v) {};
private:
int val;
};
main() {
int number;
A a; /* GOOD, object of type A, created without arguments */
A b(2); /* GOOD, object of type A, created with one argument */
A c(); /* BAD, C++ thinks this is declaration of
a function returning class A as a type */
A(d); /* GOOD, object of type A again; no arguments */
A(number); /* BAD, tries to re-declare "number" as object of type A */
}
我想我明白为什么可以创建对象“a”,“b”和“d”,而其余的则不能。
但我真的需要最后一个声明的语法,即
A(number);
创建一个临时对象,作为参数传递给另一个对象。
任何想法如何解决它?
Kind regards
答案 0 :(得分:1)
您的目的是创建一个临时对象,但此对象 也匿名:分号后无法引用它。 创建匿名临时对象只是为了丢弃它没有意义。您必须直接在将使用它的ctor /方法的调用站点实例化您的临时文件。
要将匿名临时对象传递给函数,实际上需要在参数列表中实例化它:
functionExpectingA(A(number));
对于“c声明”这一行,你正在寻找most vexing parse。如果您确实需要将默认构造的A
对象作为参数传递给另一个对象构造函数,则需要添加另一对大括号来执行该操作(因此编译器可以将其与函数声明区分开来):
class OtherClass
{
public:
OtherClass(A a)
{
//...
};
};
OtherClass obj((A()));
^ ^
编辑#1 : jrok 指出,给予 A 构造函数的参数不足以解决歧义。
如果你需要传递一个用参数构建的匿名临时对象,没有歧义(所以不需要额外的括号),你仍然需要围绕匿名对象构造的括号:
OtherClass obj((A(number)));
编辑#2 :“为什么给A构造函数提供单个参数不能解决歧义”。
OtherClass obj(A(number));
会发生什么?
这是一个名为obj
的函数的声明,它将A
对象作为其唯一参数。这个参数被命名为数字
即:它完全等同于OtherClass obj(A number);
。当然,您可以在函数声明中省略参数名称。所以它在语义上等同于OtherClass obj(A);
The syntax with parentheses around the object name is inherited from C:
int(a); // declares (and defines) a as an int.
int a; // strictly equivalent.
如果您向OtherClass
添加了一个ctor,其中包含两个(或更多)参数:
OtherClass(A a1, A a2)
{
//...
};
然后这句法语:
A arg1, arg2;
OtherClass obj(A(arg1, arg2));
这次实际上会将obj
声明为OtherClass
的实例
这是因为A(arg1, arg2)
不能解释为A
的名称声明。所以它实际上是使用带有2个参数的构造函数解析为匿名A
对象的构造。