std::vector.at().它 return 是参考还是副本?

std::vector.at(). Does it return a reference or a copy?

我刚开始学习 C++,正在尝试 std::vector 的工作原理。

我有这个测试程序:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> element1 = { 1, 2,3 };
    std::vector<int> element2 = { 4, 5, 6 };
    std::vector<std::vector<int>> lista = { element1, element2 };

    std::vector<int> var = lista.at(0);

    for (std::vector<int>::const_iterator i = var.begin(); i != var.end(); ++i)
        std::cout << *i << ' ';
    std::cout << std::endl;
    var[0] = 22;


    for (std::vector<int>::const_iterator i = var.begin(); i != var.end(); ++i)
        std::cout << *i << ' ';
    std::cout << std::endl;


    for (std::vector<int>::const_iterator i = lista.at(0).begin(); i != lista.at(0).end(); ++i)
        std::cout << *i << ' ';
    std::cout << std::endl;

    return 0;
}

输出:

1 2 3
22 2 3
1 2 3

我认为 at 运算符不是 return 引用(但也许我错了),所以我认为它 return 是一个新向量,不是吗?

但是,如果我想获得参考,我该怎么做呢?

更新:

并且...如果我想在 lista 中获取 element1element2 的引用而不是副本?

at returns 参考(以及 const 版本的 const 参考)。

您的问题是您使用 std::vector<int> var = lista.at(0); 在您的代码中获取了显式值副本。明显的修复是 auto& var = lista.at(0);.

最后,如果您希望避免 element1element2 的值副本,您可以删除它们并写入

std::vector<std::vector<int>> lista = { { 1, 2,3 }, { 4, 5, 6 } };

相反。

参考:http://en.cppreference.com/w/cpp/container/vector/at

at returns 参考。

你在这里保存一份副本std::vector<int> var = lista.at(0);

您可能会 std::vector<int>& var = lista.at(0); 以获得参考。

var 不是引用,它只是另一个变量,如下面的 b

int a = 5;
int b = a;
int &bref = a;
b=6;
cout<<a<<endl; // a is still 5
bref = 6;
cout<<a<<endl; // a is now 6

你想要的是 bref 而不是 b

std::vector<int> &var = lista.at(0);

I think that at operator doesn't return a reference (but maybe I'm wrong)

你确实错了。 vector::at returns 一个引用,如声明所示:

reference       at( size_type pos );
const_reference at( size_type pos ) const;

但是,std::vector<int> var 不是引用,您可以从返回的引用复制初始化它。

But, if I want to get a reference, how can I do it?

要获取引用,您需要一个引用变量,您可以在其中捕获 at:

返回的引用
std::vector<int>& var = lista.at(0);
//              ^ a reference

And also here, std::vector<std::vector<int>> lista = { element1, element2 };, I think there is a copy of element1 and element2 in lista vector.

没错。

If I don't want to create a copy of element1 and element2, what do I have to do?

如果您不想在外部向量中存储向量(的副本),那么您需要存储其他内容。您不能在容器中存储引用,但可以存储 std::reference_wrapper 或指针。例如:

std::vector<std::vector<int>*> lista = { &element1, &element2 };

然后您可以使用间接运算符获取指向向量的引用。


从你的例子中不清楚你想做什么,也许有一个向量的向量可能有意义,让 element1element2 成为参考:

std::vector<std::vector<int>> lista = {
    { 1, 2, 3 },
    { 4, 5, 6 },
};
std::vector<int>& element1 = lista[0];
std::vector<int>& element2 = lista[1];

如果你只是想避免复制子向量的内容,并且你不打算在之后使用element1element2,那么还有另一种方法:你可以移动构造lista 的子向量:

std::vector<std::vector<int>> lista = {
    std::move(element1),
    std::move(element2),
};
// element1 and elemenet2 are now in an unspecified state