我正在阅读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规范&所有都显示相同。
答案 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年间发生的变化尚不清楚。