4

我有以下代码:

enum nums {
  a
};

class cls {
public:
  cls( nums );
};

void function()
{
  cls( a );
}

当我尝试使用 gcc 编译它时,出现以下错误:

test.cpp: In function ‘void function()’:
test.cpp:12:10: error: no matching function for call to ‘cls::cls()’
test.cpp:12:10: note: candidates are:
test.cpp:7:3: note: cls::cls(nums)
test.cpp:7:3: note:   candidate expects 1 argument, 0 provided
test.cpp:5:7: note: cls::cls(const cls&)
test.cpp:5:7: note:   candidate expects 1 argument, 0 provided
make: *** [test] Error 1

如果我用这个替换函数:

void function()
{
  cls name( a );
}

然后一切正常。如果我使用带有两个参数的构造函数,它也可以工作。如果我在构造函数中添加“显式”,它将不起作用。

我知道 gcc 以某种方式将其解析为定义名称为“a”的“cls”类型的变量,但我不熟悉这种用于定义变量的语法。在我看来,这是一个定义 cls 类型的匿名临时变量的语句,传递“a”是参数。

使用 gcc 4.6.3 编译。

有什么见解吗?

谢谢,沙查尔

4

2 回答 2

10

最尴尬的解析问题的另一个例子。该行:

cls( a );

声明一个名为atype的局部变量cls,它是(或应该)通过调用默认构造函数来初始化的。哪个不存在,错误消息从何而来。

如果您真的想构造一个临时对象,该对象将在之后立即销毁,您可以通过将整个表达式放在括号中来消除歧义:

(cls( a ));

定义不能出现在括号中;一个表达式可以。

于 2013-07-11T13:05:59.993 回答
8

括号是可选的。Socls (a);与 相同cls a;,它声明一个 a类型的对象cls并默认初始化它(由于没有匹配的构造函数而失败)。

要创建一个在表达式末尾过期的临时值,您可以cls { a };在 C++11 中说,或(cls(a));(或任何数量的更神秘的构造,如void(0), cls(a);)。

有关更多想法,请参阅此答案

于 2013-07-11T13:04:51.170 回答