为什么std :: runtime_error的c'tor采用对std :: string的常量引用?

时间:2018-02-28 18:06:11

标签: c++ exception memory-management reference

根据cppreference.comstd::runtime_error的一位成员有以下签名:

explicit runtime_error( const std::string& what_arg );

但是(我假设)新构造的异常对象需要保存该std::string参数的副本。那么为什么const ref(而不是值)给出了论证?

我的假设是错的吗?

2 个答案:

答案 0 :(得分:5)

无论如何,按值传递都没有用。不过,您可能正在考虑传递std::string&&。根据您发布的cppreference.com page

  

因为不允许复制std :: exception来抛出异常,所以此消息通常在内部存储为单独分配的引用计数字符串。这也是没有构造函数采用std :: string&&的原因:它无论如何都必须复制内容。

std::runtime_error不应该持有std::string,因为如果这样做,复制异常可能会因为无法为副本分配空间而导致另一个异常。避免这种情况的一种方法是使用引用计数缓冲区并将参数复制到该缓冲区。鉴于必须制作副本,std::string&&重载不会带来任何好处。

答案 1 :(得分:2)

您应该始终将字符串作为const引用。它避免制作两个副本。

如果您将其作为字符串接受,则必须先构建它。然后当把它放入类成员时,它必须复制构造它。

对于移动操作,这可能效率不高,但是我们中的一些人仍然必须为Visual Studio 2008或Redhat Linux 5编写C ++代码,并且不能使用C ++ 11,14或17。

除此之外,当创建std :: exception时,C ++标准中没有任何移动操作。