应该std :: copy()或std :: move()的空范围需要有效的目的地吗? [英] should std::copy() or std::move() of empty range require valid destination?

查看:166
本文介绍了应该std :: copy()或std :: move()的空范围需要有效的目的地吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码中的 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 if j is reachable from i.

同一节的p6说明:


迭代器 j 被称为从迭代器可达 i if并且只有
,如果存在表达式 ++ i
的应用程序的有限序列,使得 i == j

An iterator j is called reachable from an iterator i if and only if there is a finite sequence of applications of the expression ++i that makes i == 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆