为什么不能构造包含 ostringstream 成员的对象?
Why can't an object containing a ostringstream member be constructed?
我有以下 class 示例,它是从一个较大的项目中简化而来的。它基于一个日志记录框架,该框架使用记录器的范围来终止析构函数中的日志条目。
下面的代码将无法编译,因为构造函数是一个隐式删除的函数(编辑:不正确),这似乎与std::ostringstream
有关目的。我对此感到困惑,因为我认为我应该能够直接构造一个 std::ostringstream
,这意味着我应该能够直接构造一个 Container
对象。
#include <iostream>
#include <sstream>
class Container {
public:
std::ostringstream bufferStream;
public:
Container(); // constructor
~Container();
};
Container::Container() {
bufferStream << "Hello ";
}
Container::~Container() {
std::cout << bufferStream.str() << " [end]" << std::endl;
}
// === Main method ===
int main() {
Container().bufferStream << "world"; // works fine
{ // causes tons of compiler errors
Container cont = Container();
cont.bufferStream << "world!";
}
return 0;
}
请注意,标有 "works fine" 的行就是这样做的。好像实例化了一个匿名的Container
对象,里面包含了一个新的std::ostringstream
,可以直接访问输出"world"。 Container
本身创建消息的 "Hello" 部分,其析构函数刷新缓冲区。
为什么命名和保存 Container
对象的第二部分 运行 不正确?这是我得到的错误示例:
error.cpp: In function ‘int main()’:
error.cpp:28:36: error: use of deleted function ‘Container::Container(const Container&)’
Container cont = Container();
^
error.cpp:4:7: note: ‘Container::Container(const Container&)’ is implicitly deleted because the default definition would be ill-formed:
class Container {
^
error.cpp:4:7: error: use of deleted function ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’
In file included from error.cpp:2:0:
/usr/include/c++/4.8/sstream:387:11: note: ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_ostringstream : public basic_ostream<_CharT, _Traits>
...等等。
这会很好:
Container cont;
cont.bufferStream << "world!";
但是这个:
Container cont = Container();
涉及拷贝构造函数。 std::ostringstream
不可复制构造,这使得 Container
不可复制构造,因此由于 std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)
被隐式删除,错误消息谈论 Container::Container(const Container&)
是如何被隐式删除的。
请注意,即使此副本会被省略,copy/move 省略的要求是 copy/move 必须可以开头。
正如 Barry 解释的那样,ostringstream
不是可复制构造的。由于默认的拷贝构造函数是逐个成员拷贝构造的,所以不能在这里生成。
但是,如果您遵循字符串流的 rule of three you'd create a copy constructor (and also a copy assignment operator), doing what is needed。然后它将起作用:
class Container {
...
Container(const Container&); //Copy constructor
};
Container::Container(const Container &c) {
bufferStream << c.bufferStream.rdbuf();
}
我有以下 class 示例,它是从一个较大的项目中简化而来的。它基于一个日志记录框架,该框架使用记录器的范围来终止析构函数中的日志条目。
下面的代码将无法编译,因为构造函数是一个隐式删除的函数(编辑:不正确),这似乎与std::ostringstream
有关目的。我对此感到困惑,因为我认为我应该能够直接构造一个 std::ostringstream
,这意味着我应该能够直接构造一个 Container
对象。
#include <iostream>
#include <sstream>
class Container {
public:
std::ostringstream bufferStream;
public:
Container(); // constructor
~Container();
};
Container::Container() {
bufferStream << "Hello ";
}
Container::~Container() {
std::cout << bufferStream.str() << " [end]" << std::endl;
}
// === Main method ===
int main() {
Container().bufferStream << "world"; // works fine
{ // causes tons of compiler errors
Container cont = Container();
cont.bufferStream << "world!";
}
return 0;
}
请注意,标有 "works fine" 的行就是这样做的。好像实例化了一个匿名的Container
对象,里面包含了一个新的std::ostringstream
,可以直接访问输出"world"。 Container
本身创建消息的 "Hello" 部分,其析构函数刷新缓冲区。
为什么命名和保存 Container
对象的第二部分 运行 不正确?这是我得到的错误示例:
error.cpp: In function ‘int main()’:
error.cpp:28:36: error: use of deleted function ‘Container::Container(const Container&)’
Container cont = Container();
^
error.cpp:4:7: note: ‘Container::Container(const Container&)’ is implicitly deleted because the default definition would be ill-formed:
class Container {
^
error.cpp:4:7: error: use of deleted function ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’
In file included from error.cpp:2:0:
/usr/include/c++/4.8/sstream:387:11: note: ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_ostringstream : public basic_ostream<_CharT, _Traits>
...等等。
这会很好:
Container cont;
cont.bufferStream << "world!";
但是这个:
Container cont = Container();
涉及拷贝构造函数。 std::ostringstream
不可复制构造,这使得 Container
不可复制构造,因此由于 std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)
被隐式删除,错误消息谈论 Container::Container(const Container&)
是如何被隐式删除的。
请注意,即使此副本会被省略,copy/move 省略的要求是 copy/move 必须可以开头。
正如 Barry 解释的那样,ostringstream
不是可复制构造的。由于默认的拷贝构造函数是逐个成员拷贝构造的,所以不能在这里生成。
但是,如果您遵循字符串流的 rule of three you'd create a copy constructor (and also a copy assignment operator), doing what is needed。然后它将起作用:
class Container {
...
Container(const Container&); //Copy constructor
};
Container::Container(const Container &c) {
bufferStream << c.bufferStream.rdbuf();
}