Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 标准副本问题_C++ - Fatal编程技术网

C++ 标准副本问题

C++ 标准副本问题,c++,C++,使用std::copy复制阵列时,是否有方法检查副本是否正确通过?特别是如果在无符号字符数组中有类似的十六进制值。我不知道如何才能验证拷贝是否通过,甚至是否正确复制了一个数组中的值 实际上,复制失败的唯一方法是复制到类似back\u insert\u迭代器的对象,在这种情况下,目标容器中的分配可能会失败。这通常会被抛出的异常报告 1对于那些想要获得血淋淋的详细信息的人,在本例中,“正常”意味着您没有提供自己的分配器,该分配器除了在失败时抛出异常之外,还可以执行其他操作 编辑:也许我应该更明确一点

使用std::copy复制阵列时,是否有方法检查副本是否正确通过?特别是如果在无符号字符数组中有类似的十六进制值。我不知道如何才能验证拷贝是否通过,甚至是否正确复制了一个数组中的值

实际上,复制失败的唯一方法是复制到类似
back\u insert\u迭代器的对象,在这种情况下,目标容器中的分配可能会失败。这通常会被抛出的异常报告

1对于那些想要获得血淋淋的详细信息的人,在本例中,“正常”意味着您没有提供自己的分配器,该分配器除了在失败时抛出异常之外,还可以执行其他操作

编辑:也许我应该更明确一点:我说的是一个你有机会发现的失败。
std::copy
的前提条件是目标迭代器不能在源范围内。违反规则会导致未定义的行为。同样,若您执行的赋值(直接或通过复制或转换等算法)超出了目标类型的范围,您(再次)会得到未定义的行为

未定义行为的定义是标准对实现没有要求。换句话说,如果你这样做,任何事情都可能发生。程序的行为没有任何保证。没有明智的方式来谈论如何检测发生了这样的事情,因为语言说如果你的程序做了这样的事情,你就不能依赖任何东西

再次编辑:因为似乎对未定义的行为有一些误解。要做任何好事,如果你关心的事情可能会导致未定义的行为,你需要防止它们发生,而不是试图复制,然后试图找出它是否成功。到那时已经太晚了;如果程序执行未定义的操作,all程序的行为未定义

因此,要处理目标迭代器在源迭代器范围内的可能性,或者源数据在目标数据类型范围之外的可能性,您需要提前检查这些迭代器,甚至不要尝试未定义的行为

template <class T, class U>
safe_copy(T source_start, T source_end, U dest) { 
    if (std::less(source_start, dest) && std::less(dest, source_end))
        throw(std::range_error("Output iterator within input range");
    std::transform(source_start, source_end, dest, checked_convert);
}
模板
安全拷贝(T源开始,T源结束,U目的){
if(std::less(源端、目的端)和&std::less(目的端、源端))
抛出(std::range_error(“输入范围内的输出迭代器”);
转换(源开始、源结束、目标、选中转换);
}

目前,我还没有尝试定义
checked\u convert
。它可能会执行饱和转换,或者在值超出范围时引发异常,等等,这完全取决于所涉及的数据类型。但是,通过这种或那种方式,它可以确保源值在分配到目标之前符合目标范围已尝试。

您可以使用以下命令再次检查复制是否成功:(
assert
来自

这将捕获由
src_first
引起的问题。但是,更好的方法是直接断言该条件:(这需要随机访问迭代器,即来自
向量
deque
,并且它们必须属于同一个容器-如果您关心重叠,通常就是这种情况)


assert(src_lastlong
范围复制到
int
范围内)。@Potatoswatter:谢谢你提出这个问题。我已经为答案添加了一点内容(希望如此)澄清与这些情况相关的情况。仍然有几个错误:目标初始迭代器不能在目标范围内;最终迭代器可能在目标范围内。不同类型不会产生未定义的行为;
copy
定义为将对象从源分配到目标,这是在源和des之间定义的定向类型定义了该操作。(如果它编译,它可能定义得很好!)换言之:
int8_t(128)
可能未定义,但
uint8_t(128)=
int8_t(128)`有100%的可能是错误的。从他的问题听起来,这正是他试图解决的问题。@Potatoswatter:(例如)编译时需要long to int,但如果值超出目标类型的范围,则会给出未定义的行为。坦率地说,这些都是无用的建议。两者都不会可靠地做任何有用的事情。在第一种情况下,您质疑硬件将数据从一个位置复制到另一个位置的能力,但假设相同的硬件将我做的比较是正确的。没有更多的理由相信比较是正确的。在第二种情况下,你比较的指针不一定(事实上通常不会)引用同一数组的某些部分--这些部分给出了未定义的结果。如果您真的想做第二部分,请使用std::less,并在复制之前进行。@Jerry:您读过我在这一页上写的任何内容吗?有两种问题很容易被忽略:范围不正确地重叠,以及由于不同类型而导致溢出。它有n这与硬件故障有关,很抱歉,您从未遇到过这些错误…总有一天您会遇到。对于未定义的结果,这是真的,我将添加一个免责声明…实际上它适用于
vector::iterate
assert ( std::equal( src_first, src_last, dst ) );
assert ( src_last < dst || dst <= src_first );