奇怪的编译器决定

时间:2013-07-11 12:58:43

标签: c++ g++

我已获得以下代码:

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 );
}
然后一切正常。如果我使用带有两个参数的构造函数,它也可以工作。如果我添加" explicit"它不起作用。到构造函数。

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

使用gcc 4.6.3编译。

任何见解?

谢谢, Shachar

2 个答案:

答案 0 :(得分:10)

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

cls( a );

声明一个名为a的{​​{1}}类型的局部变量,它是(或 应该)通过调用默认构造函数初始化。 哪个不存在,从而出现错误信息。

如果你真的想构建一个临时对象 紧接着被破坏后,你可以消除歧义 将整个表达式括在括号中:

cls

括号中不能出现定义;表达可以。

答案 1 :(得分:8)

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

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

有关更多提示,请参阅this answer

相关问题