应该std :: copy()或std :: move()的空范围需要有效的目的地吗? [英] should std::copy() or std::move() of empty range require valid destination?
问题描述
下面的代码中的 std :: move()
在Visual Studio 2013(使用Debug配置)中编译时会发出运行时警告,因为它检测到 dest
是一个 nullptr
。但是,源范围为空,因此不应访问 dest
。
C ++标准可能不清楚是否应该允许这样做?
它说明:需要:结果不在[first,last]范围内。
A nullptr
以满足该要求。
The std::move()
in the code below issues a runtime warning when compiled in Visual Studio 2013 (with Debug configuration) because it detects that dest
is a nullptr
. However, the source range is empty, so dest
should never be accessed.
The C++ standard may be unclear as to whether this should be allowed?
It states: Requires: result shall not be in the range [first,last).
A nullptr
would seem to satisfy that requirement.
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec;
int* dest = nullptr;
// The range [begin(vec),end(vec)) is empty, so dest should never be accessed.
// However, it results in an assertion warning in VS2013.
std::move(std::begin(vec), std::end(vec), dest);
}
推荐答案
> Requires:子句中的所有内容都需要满足,但是效果:和返回:让我们通过他们:
Not only does the Requires: clause need to be satisfied, but everything in the Effects: and Returns: clause needs to be satisfied as well. Let's go through them:
效果:复制
最后)
进入范围[result,result +(last - first))
从开始
和
转到最后
。
c $ c> first == last ,则范围 [result,result + 0)
必须是有效的范围。
As first == last
, then the range [result, result + 0)
must be a valid range.
[iterator.requirements.general] / p7状态:
[iterator.requirements.general]/p7 states:
范围
[i,i]
是一个空的范围; ...当且仅当
j
可从
A range
[i,i)
is an empty range; ...Range [i,j)
is valid if and only ifj
is reachable fromi
.
同一节的p6说明:
迭代器
j
被称为从迭代器可达i
if并且只有
,如果存在表达式++ i
的应用程序的有限序列,使得i == j
。
An iterator
j
is called reachable from an iteratori
if and only if there is a finite sequence of applications of the expression++i
that makesi == j
.
从这些段落中我得出结论:
From these paragraphs I conclude that given:
int* dest = nullptr;
然后 [dest,dest)
有效空范围。因此,效果:段中的第一个句子对我来说是正确的:
Then [dest, dest)
forms a valid empty range. So the first sentence in the Effects: paragraph looks ok to me:
对于每个非负整数
n < (最后一个)
,执行*(result + n)= *(first + n)
。
没有非负整数 n< 0
,因此不能执行分配。所以第二句不禁止 dest == nullptr
。
There are no non-negative integers n < 0
, and so no assignments can be performed. So the second sentence does not prohibit dest == nullptr
.
返回:
result +(last- first)
。
< [expr.add] / p8具体允许一个将0加到任何指针值,结果比较等于原始指针值。因此, dest + 0
是等于 nullptr
的有效表达式。 子句无问题。
[expr.add]/p8 specifically allows one to add 0 to any pointer value and the result compares equal to the original pointer value. Therefore dest + 0
is a valid expression equal to nullptr
. No problems with the Returns: clause.
需要: c> result 不得在
[first,last]
范围内。
Requires:
result
shall not be in the range[first,last)
.
我认为没有合理的方法来解释 dest
会是in一个空的范围。
I see no reasonable way to interpret that dest
would be "in" an empty range.
复杂性:完全
最后一个
作业
这可以确认没有任何分配。
This confirms that no assignments can be done.
我可以在标准中找不到任何语句,形式良好。
I can find no statement in the standard that makes this example anything but well-formed.
这篇关于应该std :: copy()或std :: move()的空范围需要有效的目的地吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!