为啥 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::any 由 std::exception_ptr

区别:std::runtime_error 与 std::exception()

error: no matching function for call to 'std::exception:exception(const char[16])'

C++ 异常和来自 std::exception 的继承