为啥 std::exception 在 VC++ 中有额外的构造函数?
Posted
技术标签:
【中文标题】为啥 std::exception 在 VC++ 中有额外的构造函数?【英文标题】:Why does std::exception have extra constructors in VC++?为什么 std::exception 在 VC++ 中有额外的构造函数? 【发布时间】:2011-03-01 16:20:32 【问题描述】:我刚才注意到的事情。 the standard (18.6.1) 中exception
的定义:
class exception
public :
exception() throw();
exception(const exception &) throw();
exception& operator=(const exception&) throw();
virtual ~exception() throw();
virtual const char* what() const throw();
;
exception
在MSDN 中的定义:
class exception
public:
exception();
exception(const char *const&);
exception(const char *const&, int);
exception(const exception&);
exception& operator=(const exception&);
virtual ~exception();
virtual const char *what() const;
;
微软的版本似乎允许您为 exception
对象指定错误消息,而标准版本只允许您为派生类执行此操作(但不会阻止您创建通用的 exception
带有未定义的消息)。
我知道这很微不足道,但仍然如此。这样做有充分的理由吗?
【问题讨论】:
我猜想存在额外的重载是因为它们存在于较旧的、可能是标准前版本的库中,但看起来它们实际上是在 Visual C++ 2005 中添加的(它们不是t 出现在 Visual C++ 2003 文档中)。 【参考方案1】:没有什么好的理由。 MS 实现选择将字符串处理放在 std::exception 中,而不是放在从它派生的每个类中 (
由于它们实际上也提供了标准所需的接口,因此可以将其视为符合标准的扩展。遵循标准的程序按预期工作。
其他实现不这样做,因此可移植程序不应使用额外的构造函数。
【讨论】:
那些额外的构造函数不是explicit
,至少不在问题的引用中。添加隐式转换不是不兼容的更改,因为它可能会破坏某人的 SFINAE 代码?
@Steve:它们可以被检测到,但我也相信允许实现添加额外的构造函数。当然,标准(17.4.4.4)说实现可以添加非虚拟成员函数。它没有明确说这包括 special 成员函数,但也不排除它们。在这种特殊情况下,我会让它们受到保护,因为它是派生类的实现细节。【参考方案2】:
摆脱 throw 规范是个好主意。尽管它们不应该投掷,但投掷规范通常很糟糕。
添加扩展将使代码不可移植,但可能会解决人们“捕获” std::exception 值的切片问题,并且它可以将字符串从它复制的内容复制到本地。
我没有看到 int 的优势,也没有看到采用一个参数的非显式构造函数。
【讨论】:
MSDN 说:“int 参数允许您指定不应分配内存。int 的值被忽略。”这又是一种混乱,你会认为他们可能只是使用了带有默认值的bool
参数。
Visual C++ 并不完全支持异常规范。
@James:异常规范似乎通常被认为是一个坏主意,并且将在下一个 C++ 标准中彻底改革。
@David:对。我的意思是,评论更多的是“使用此标准库实现的编译器不支持异常规范,这可能是它们不存在的原因。”不过我可能是错的;可能还有其他原因。以上是关于为啥 std::exception 在 VC++ 中有额外的构造函数?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Alexandrescu 不能使用 std::uncaught_exception() 在 ScopeGuard11 中实现 SCOPE_FAIL? [复制]
抛出新的 std::exception 与抛出 std::exception
区别:std::runtime_error 与 std::exception()
error: no matching function for call to 'std::exception:exception(const char[16])'