Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.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++ std::复制不';t更改目标向量大小_C++_C++11_Copy_Stdvector_Stl Algorithm - Fatal编程技术网

C++ std::复制不';t更改目标向量大小

C++ std::复制不';t更改目标向量大小,c++,c++11,copy,stdvector,stl-algorithm,C++,C++11,Copy,Stdvector,Stl Algorithm,如果我为一个向量保留一些空间,然后用std::copy_n()复制其中的一些值,我会得到正确复制且可访问的值,但向量的大小仍然为零。这是预期的行为吗?我是否应该调整向量的大小,即使它没有那么有效 #include <algorithm> #include <iostream> #include <vector> int main() { std::vector<double> src, dest; for(double x =

如果我为一个向量保留一些空间,然后用
std::copy_n()
复制其中的一些值,我会得到正确复制且可访问的值,但向量的大小仍然为零。这是预期的行为吗?我是否应该调整向量的大小,即使它没有那么有效

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
    std::vector<double> src, dest;

    for(double x = 0.0; x < 100.0; ++x)
        src.push_back(x);

    dest.reserve(src.size());

    std::copy_n(src.cbegin(), src.size(), dest.begin());

    std::cout << "src.size() = " << src.size() << std::endl;
    std::cout << "dest.size() = " << dest.size() << std::endl;

    for(size_t i = 0; i < src.size(); ++i)
        std::cout << dest[i] << "  ";

}
#包括
#包括
#包括
int main()
{
std::向量src,dest;
用于(双x=0.0;x<100.0;++x)
src.推回(x);
目的地储备(src.size());
std::copy_n(src.cbegin()、src.size()、dest.begin());
标准::cout
但是向量的大小仍然是零

std::copy\n
不会更改容器的大小,只需复制值并步进迭代器;它甚至没有关于容器的任何信息。因此代码具有未定义的行为,即使它看起来工作正常

我是否应该调整向量的大小,即使它没有那么有效

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
    std::vector<double> src, dest;

    for(double x = 0.0; x < 100.0; ++x)
        src.push_back(x);

    dest.reserve(src.size());

    std::copy_n(src.cbegin(), src.size(), dest.begin());

    std::cout << "src.size() = " << src.size() << std::endl;
    std::cout << "dest.size() = " << dest.size() << std::endl;

    for(size_t i = 0; i < src.size(); ++i)
        std::cout << dest[i] << "  ";

}
是的,您可以使用
std::vector::resize
而不是
std::vector::reserve
来解决此问题。正如您可能想到的,这意味着所有元素都将首先通过
resize
构建,然后通过
copy\n
分配

您可以使用,它将通过调用容器的
push_back()
成员函数(即直接构造元素)在容器的末尾追加元素,从而增加容器的大小

dest.reserve(src.size());
std::copy_n(src.cbegin(), src.size(), std::back_inserter(dest));

std::vector具有大小和容量。它保留了一些超出必要的空间,以加快插入速度。reserve允许您指定该容量,而resize会更改向量的实际大小。

在调用
reserve
后,您的
dest
分配了存储元素的内存,但它不会调用构造函数和它实际上是空的,因此您的代码将导致UB。使用
resize
实际创建这些元素,然后就可以了

dest.resize(src.size());
std::copy_n(src.cbegin(), src.size(), dest.begin());

std::cout << "src.size() = " << src.size() << std::endl;
std::cout << "dest.size() = " << dest.size() << std::endl;

for(size_t i = 0; i < src.size(); ++i)
    std::cout << dest[i] << "  ";
dest.resize(src.size());
std::copy_n(src.cbegin()、src.size()、dest.begin());

std::cout关于标准库算法,需要记住的关键是它们在范围上操作,而不是容器。容器是创建范围的方法之一,但不是唯一的方法。将结果写入范围的算法假定它们正在写入有效的位置;它们没有,也不能,extend他们正在写入的范围

因此,当您调用
std::copy\n
时,必须提供一个足够大的范围来容纳结果。这意味着使用
dest.resize(src.size());
设置范围,而不仅仅是使用
dest.reserve(std.size());
分配内存


或者,您可以通过使用
std::back_inserter(dest)
而不是
dest.begin()

调用算法,来提供一个知道它已连接到容器并且需要调整大小的范围
只影响容量,不影响大小。@RawN,是的,但我希望
copy\n
来更新大小。你知道你可以简单地做dest=src吗?你知道vector的赋值函数吗?@mann66:是的。我把代码简化了,但src可能不是std::vector。@Pietro显然不是:operator=将一个向量赋值给另一个向量,copy_n将一个范围复制到另一个范围。我假设运算符=ist更快。它肯定更安全。vector::assign与copy_n有更多的共同点,但它永远不会在分配的空间之外写入。std::back_inserter
是否比
std::vetor::resize
然后复制慢得多?@KamilKoczurek否。它将调用contai内尔的
push_-back
直接追加元素;而不是通过
调整大小来构造所有元素,然后分配它们。对,我没有意识到你调用
std::vetor::reserve
,所以不需要重新分配内存,我的错。@KamilKoczurek这很好。事实上,我在年第一次明确地写了这篇文章我的回答。