Tr0*_*03P 3 c++ compiler-errors language-lawyer
在作用域中创建临时对象时,编译器不会看到构造函数提供的参数并给出编译错误.
如下例所示:
#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;
}
Run Code Online (Sandbox Code Playgroud)
我收到这个错误.
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
Run Code Online (Sandbox Code Playgroud)
尝试使用gcc 7.3和5.4
当我命名临时对象时它起作用了 { csventry entry(log); }
为什么编译器错过了提供的参数?
son*_*yao 10
csventry(log);不会像您期望的那样创建临时对象; 括号被认为是多余的,实际上它声明了一个以log类型命名的对象csventry,即它与...相同csventry log;.正如错误消息所述,它失败了,因为csventry没有默认构造函数.
作为解决方法,您可以将其更改为csventry{log};.
(强调我的)
在涉及表达式语句和声明的语法中存在歧义:具有函数式显式类型转换的表达式语句,因为其最左侧的子表达式与第一个声明符以a开头的声明无法区分(.在这些情况下,语句是宣言.