basic_string类是否真的具有需要多个参数的复制构造函数,还是只是构造函数?

时间:2015-10-06 18:20:13

标签: c++ string parameters copy-constructor stdstring

我正在阅读Why would a copy constructor have more than one parameter?

接受的答案是:

std::basic_string也有一个:

basic_string(const basic_string& s, 
         size_type pos = 0, size_type n = npos)

但是http://www.cplusplus.com/reference/string/basic_string/basic_string/说:

basic_string (const basic_string& str, size_type pos, size_type len = npos,
              const allocator_type& alloc = allocator_type());

以上不是复制构造函数,而是子串构造函数,用于复制str从字符位置pos开始并跨越len个字符的部分。

C ++标准部分说:

  

类X的非模板构造函数是复制构造函数(如果是)   第一个参数是X&类型,const X&,volatile X&或const volatile   X&,并且没有其他参数或其他所有参数   参数有默认参数

那么,该链接的接受答案是否不正确?这是子串的真正basic_string类构造函数吗?我在C ++ 98,C ++ 11& C中检查了原型。链接上的C ++ 14规范&所有都显示相同。

2 个答案:

答案 0 :(得分:5)

(以前的)C ++ 11国际标准[basic.string] p5中basic_string类模板的规范包含以下两个构造函数(以及其他):

basic_string(const basic_string& str);
// ...
basic_string(const basic_string& str, size_type pos, size_type n = npos,
             const Allocator& a = Allocator());

第一个显然是复制构造函数,第二个是没有复制构造函数。请注意,规范中有构造函数,其中pos具有默认参数。

C ++ 03,C ++ 14和C ++ 1z中的情况基本相同。在C ++ 98中,这两个构造函数确实只有一个:

 basic_string(const basic_string& str, size_type pos = 0, size_type n = npos,
 //                                                 ~~~~
              const Allocator& a = Allocator());

但由于LWG 42,这已被更改为当前版本的两个独立构造函数。

<击> 据我所知,允许C ++标准库的实现将这两个构造函数合并为一个,然后成为复制构造函数

 basic_string(const basic_string& str, size_type pos = 0, size_type n = npos,
 //                                                 ~~~~
              const Allocator& a = Allocator());

<击>

这有不同的行为。如LWG 42中所述(请参阅Shafik Yaghmour's answer),basic_string的实际副本ctor获取str分配器的副本,而默认情况下为“substring”构造函数使用值初始化的新对象。

感谢Sebastian Redl指出这一点。

答案 1 :(得分:3)

所以“old”,回到1998年的规范与original SO answer the OP points to非常类似,并且至少改变了一次到今天的状态。

可以在LWG issue 42: String ctors specify wrong default allocator中找到1998规范:

  

basic_string&lt;&gt;复制构造函数:

basic_string(const basic_string& str, size_type pos = 0,
             size_type n = npos, const Allocator& a = Allocator()); 
     

指定一个Allocator参数默认值   反直觉。分配器复制的自然选择   是str.get_allocator()。虽然这不能表达出来   default-argument表示法,重载就足够了。

并提出以下可能的解决方案:

  

B中。在21.3 [lib.basic.string]中,以及在21.3.1 [lib.string.cons]中,   替换复制构造函数的声明,如下所示:

basic_string(const basic_string& str, size_type pos = 0,
             size_type n = npos);
     

℃。在21.3 [lib.basic.string]中,替换副本的声明   构造函数如下:

basic_string(const basic_string& str);
basic_string(const basic_string& str, size_type pos, size_type n = npos,
             const Allocator& a = Allocator());
     

在21.3.1 [lib.string.cons]中,替换上面的复制构造函数声明。添加到第5段,效果:

     

在第一种形式中,使用的Allocator值是从str.get_allocator()复制的。

第一个修复与original SO answer the OP points to匹配,第二个修复与我们今天的匹配。

该LWG问题是从1998年开始的,这可能是为什么今天的公共草案都没有任何证据证明这一点。最早的公开草案N1804是从2005年开始的。1998年至2005年间发生的变化尚不清楚。