编译错误:临时对象构造函数中缺少参数

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};.

[stmt.ambig]/1:

(强调我的)

在涉及表达式语句和声明的语法中存在歧义:具有函数式显式类型转换的表达式语句,因为其最左侧的子表达式与第一个声明符以a开头的声明无法区分(.在这些情况下,语句是宣言.

  • @Yksisarvinen因为你可以在声明中使用(),例如`int(*funcptr)();` (2认同)