Bil*_*eal 8 c++ algorithm stl stl-algorithm
我在N3485 25.3.1 [alg.copy]中查看了C++标准,它定义了4种算法:
copycopy_backwardcopy_ifcopy_n在描述中copy,有这个注释25.3.1 [alg.copy]/3:
要求:结果不应在[first,last]范围内
也就是说,copy当范围重叠(类似于memcpy)时,并不总是正常工作.
copy_backward并且copy_if有类似的语言禁止重叠范围(分别为25.3.1 [alg.copy]/14和25.3.1 [alg.copy]/8).
但是,没有这样的禁令copy_n,也没有copy_n_backward.这是否意味着copy_n当范围重叠时做正确的事情?
(MSVC++的实现copy_n似乎委托给了std::memmove,所以我知道它在MSVC++ 2013上是安全的.但是如果标准暗示的话,我不想依赖它)
这是安全的*。为什么?因为标准并没有说它不安全。他们从 25.3.1 复制函数有Requires:对于他们需要的东西(这是其他复制形式中规定重叠禁止的地方)。
但是,并没有copy_n说它要求范围不重叠,这意味着可以,因为它没有明确禁止。如果需要的话,它会说明这一点。
*编辑:当我的意思是“安全”时,我的意思是这不是未定义的行为或不正确的程序。但是,如果内存范围重叠,则不能保证结果符合您的预期。我们唯一能保证的是:
i < n,*(result + i) = *(first + i)执行因此,我们可以推断,如果范围重叠,则不再保证存储在目标中的结果是源的精确(按顺序)副本。我们保证目标中的每个值都来自源,尽管这些值的确切值取决于重叠和复制元素的确切顺序。
因此,如果“安全”意味着目标始终具有源的完美副本(例如memmove),那么不,它不是“安全”。但它是安全的,因为它本身不会导致未定义/无效的行为。
回顾一下,我们保证*(result + i) = *(first + i)会对整个范围中的每个元素进行处理。我们保证,如果范围重叠,程序仍然不是未定义的。我们不保证复制元素的顺序。我们不能保证如果范围重叠,结果中存储的确切值是什么(但我们确实知道它们都来自源)。