basic_string class 是否真的有接受多个参数的复制构造函数,或者它只是构造函数?
Does basic_string class really have copy constructor that takes more than one parameter or is it just constructor?
我正在阅读 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++ 标准部分说:
A non-template constructor for class X is a copy constructor if its
first parameter is of type X&, const X&, volatile X& or const volatile
X&, and either there are no other parameters or else all other
parameters have default arguments
那么,link 接受的答案是错误的吗?这真的是 basic_string class 子字符串的构造函数吗?我已经在 link 上的 C++98、C++11 和 C++14 规范中检查了原型,所有显示都相同。
(前)C++11 国际标准 [basic.string]p5 中 basic_string
class 模板的规范包含以下两个构造函数(以及其他构造函数):
basic_string(const basic_string& str);
// ...
basic_string(const basic_string& str, size_type pos, size_type n = npos,
const Allocator& a = Allocator());
第一个明明是拷贝构造函数,第二个不是拷贝构造函数。请注意,规范中没有 no 构造函数,其中 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 ),basic_string
的实际复制构造函数获取了 str
分配器的副本,而 "substring" 构造函数默认使用一个值-初始化新对象。
感谢 Sebastian Redl 指出这一点。
所以 "old",追溯到 1998 年的规范与 original SO answer the OP points to 中的规范非常相似,并且至少更改了一次今天。
可在 LWG issue 42: String ctors specify wrong default allocator:
中找到引用的 1998 规范
The basic_string<> copy constructor:
basic_string(const basic_string& str, size_type pos = 0,
size_type n = npos, const Allocator& a = Allocator());
specifies an Allocator argument default value that is
counter-intuitive. The natural choice for a the allocator to copy from
is str.get_allocator(). Though this cannot be expressed in
default-argument notation, overloading suffices.
并提出以下可能的修复方法:
B. In 21.3 [lib.basic.string], and also in 21.3.1 [lib.string.cons],
replace the declaration of the copy constructor as follows:
basic_string(const basic_string& str, size_type pos = 0,
size_type n = npos);
C. In 21.3 [lib.basic.string], replace the declaration of the copy
constructor as follows:
basic_string(const basic_string& str);
basic_string(const basic_string& str, size_type pos, size_type n = npos,
const Allocator& a = Allocator());
In 21.3.1 [lib.string.cons], replace the copy constructor declaration as above. Add to paragraph 5, Effects:
In the first form, the Allocator value used is copied from str.get_allocator().
第一个修复与 original SO answer the OP points to 相匹配,第二个与我们今天所拥有的相匹配。
这个 LWG 问题是从 1998 年开始的,这可能就是为什么今天可用的 public 草稿中的 none 有任何证据表明这一点。最早的 public 可用草案 N1804
是 2005 年的。1998 年和 2005 年之间发生了什么变化尚不清楚。
我正在阅读 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++ 标准部分说:
A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments
那么,link 接受的答案是错误的吗?这真的是 basic_string class 子字符串的构造函数吗?我已经在 link 上的 C++98、C++11 和 C++14 规范中检查了原型,所有显示都相同。
(前)C++11 国际标准 [basic.string]p5 中 basic_string
class 模板的规范包含以下两个构造函数(以及其他构造函数):
basic_string(const basic_string& str); // ... basic_string(const basic_string& str, size_type pos, size_type n = npos, const Allocator& a = Allocator());
第一个明明是拷贝构造函数,第二个不是拷贝构造函数。请注意,规范中没有 no 构造函数,其中 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 basic_string
的实际复制构造函数获取了 str
分配器的副本,而 "substring" 构造函数默认使用一个值-初始化新对象。
感谢 Sebastian Redl 指出这一点。
所以 "old",追溯到 1998 年的规范与 original SO answer the OP points to 中的规范非常相似,并且至少更改了一次今天。
可在 LWG issue 42: String ctors specify wrong default allocator:
中找到引用的 1998 规范The basic_string<> copy constructor:
basic_string(const basic_string& str, size_type pos = 0, size_type n = npos, const Allocator& a = Allocator());
specifies an Allocator argument default value that is counter-intuitive. The natural choice for a the allocator to copy from is str.get_allocator(). Though this cannot be expressed in default-argument notation, overloading suffices.
并提出以下可能的修复方法:
B. In 21.3 [lib.basic.string], and also in 21.3.1 [lib.string.cons], replace the declaration of the copy constructor as follows:
basic_string(const basic_string& str, size_type pos = 0, size_type n = npos);
C. In 21.3 [lib.basic.string], replace the declaration of the copy constructor as follows:
basic_string(const basic_string& str); basic_string(const basic_string& str, size_type pos, size_type n = npos, const Allocator& a = Allocator());
In 21.3.1 [lib.string.cons], replace the copy constructor declaration as above. Add to paragraph 5, Effects:
In the first form, the Allocator value used is copied from str.get_allocator().
第一个修复与 original SO answer the OP points to 相匹配,第二个与我们今天所拥有的相匹配。
这个 LWG 问题是从 1998 年开始的,这可能就是为什么今天可用的 public 草稿中的 none 有任何证据表明这一点。最早的 public 可用草案 N1804
是 2005 年的。1998 年和 2005 年之间发生了什么变化尚不清楚。