在创建一个简单的异常类扩展(我可以更容易地构造错误消息)时,我将错误分解为以下简单代码:
#include <sstream>
#include <string>
class myCout {
public:
std::stringstream ssOut; // Removing this gets rid of error
template <typename T> myCout& operator << (const T &x) {
// Do some formatting
return *this;
}
};
class myErr : public myCout {
public:
using myCout::operator<<;
};
int main(int argc, const char* argv[]) {
throw myErr() << "ErrorMsg" << 1;
myCout() << "Message Will Be Formatted";
return 0;
}
在编译时会产生此错误:
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\sstream(724): error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\ios(176) : see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> This diagnostic occurred in the compiler generated function 'std::basic_stringstream<_Elem,_Traits,_Alloc>::basic_stringstream(const std::basic_stringstream<_Elem,_Traits,_Alloc> &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Alloc=std::allocator<char>
1> ]
(实际上它更复杂并且扩展了像std::runtime_error
)
我看到previous answers表示问题是由于没有通过引用传递流而产生的,但我看不出我是怎么回事。
评论std::stringstream ssOut
可以解决问题。为什么,以及如何解决潜在问题?
答案 0 :(得分:6)
您正在按值抛出异常,这确实是建议的做法。但是,这意味着异常将作为throw
语句的一部分进行复制,因此它必须具有可访问的复制构造函数。因为您有一个不可复制的成员(std::stringstream
),所以您必须提供自己的副本。