在范围内创建临时对象时,编译器看不到构造函数提供的参数,并给出了编译错误。
如以下示例所示:
#include <sstream>
#include <iostream>
class csventry
{
public:
csventry(std::ostream& ostream) :
_ostream(ostream)
{}
~csventry()
{ _ostream << std::endl; }
csventry& operator << (const std::string& value) {
_ostream << ", ";
_ostream << value;
return *this;
}
private:
std::ostream& _ostream;
};
int main ()
{
std::ostringstream log;
{ csventry(log) << "User Log-on:"; }
{ csventry(log); }
{ csventry(log) << "Summary:"; }
std::cout<<log.str()<<std::endl;
}
我收到此错误。
main.cpp: In function ‘int main()’:
main.cpp:29:16: error: no matching function for call to ‘csventry::csventry()’
{ csventry(log); }
^
main.cpp:7:2: note: candidate: csventry::csventry(std::ostream&)
csventry(std::ostream& ostream) :
^~~~~~~~
main.cpp:7:2: note: candidate expects 1 argument, 0 provided
main.cpp:4:7: note: candidate: constexpr csventry::csventry(const csventry&)
class csventry
^~~~~~~~
main.cpp:4:7: note: candidate expects 1 argument, 0 provided
尝试使用gcc 7.3和5.4
当我命名临时对象{ csventry entry(log); }
为什么编译器会错过提供的参数?
答案 0 :(得分:10)
csventry(log);
并没有按您预期的那样创建临时对象。括号被认为是多余的,实际上它声明了一个类型为log
的名为csventry
的对象,即它与csventry log;
相同。如错误消息所述,它失败是因为csventry
没有默认的构造函数。
作为解决方法,您可以将其更改为csventry{log};
。
(重点是我的)
语法中涉及表达式语句和声明的模棱两可:具有函数式显式类型转换的表达式语句作为其最左边的子表达式可以与第一个声明符以(.. >在这种情况下,声明是声明。