问题:
1) 如果view函数定义为:
void view(std::ostream output, std::string text) // (1)
{
output << text;
}
并使用:
view(std::cout, "Hello, World!"); // (2)
然后编译器给出一条错误消息:
在 MSVC 中:
error C2280: 'std::basic_ostream<char,std::char_traits<char>>::basic_ostream(const std::basic_ostream<char,std::char_traits<char>> &)': attempting to reference a deleted function
海合会:
error: use of deleted function 'std::basic_ostream<_CharT, _Traits>::basic_ostream(const std::basic_ostream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
铛:
error: call to deleted constructor of 'std::ostream' (aka 'basic_ostream<char>')
2) 对于声明
std::ostream os;
显示以下错误消息:
MSVC:
error C2512: 'std::basic_ostream<char,std::char_traits<char>>': no appropriate default constructor available
海合会:
error: 'std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char; _Traits = std::char_traits<char>]' is protected within this context
铛:
error: calling a protected constructor of class 'std::basic_ostream<char>'
原因:
这都是根据std::basic_ostream的规范
没有默认构造函数的定义 - 因此std::ostream,如果没有特定的构造函数参数,就无法创建该类型的变量。
正如 C++ Reference 所说的std::basic_ostream 复制构造函数:
复制构造函数受到保护,并被删除。输出流不可复制。
解释:
1)所以问题是(2)参数std::cout被传递给一个函数,该函数被定义(1)为复制std::ostream到变量output中。
但是类的定义说不能使用复制构造函数,所以编译器给出了错误信息。
2)在创建变量的情况下os- 它没有给出任何构造函数参数,没有默认构造函数,因此编译器给出了错误消息。
如何解决这个问题?
1) 在函数的声明中更改定义以将引用 ( &)std::ostream作为参数:
void view(std::ostream& output, std::string text) // (1)
这允许它使用原始对象而不是制作副本(不允许复制)。
2)如果需要一个变量,那么也应该使用一个引用;
std::ostream& out = std::cout;