的std :: vector.at()。它是返回引用还是副本?

时间:2018-04-20 09:58:00

标签: c++ stdvector

我刚刚开始学习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

我认为在操作员处没有返回引用(但也许我错了),所以我认为它返回一个新的向量,不是吗?

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

更新

并且...如果我想要lista element1element2的引用而不是副本?{/ p>

4 个答案:

答案 0 :(得分:10)

at会返回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

答案 1 :(得分:5)

svg会返回参考。

您可以将其存储在at

的副本中

您可以std::vector<int> var = lista.at(0);进行参考。

答案 2 :(得分:4)

  

我认为在运营商处不会返回引用(但也许我错了)

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

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

但是,std::vector<int> var不是引用,您可以从返回的引用中对其进行初始化。

  

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

要获得引用,您需要一个引用变量,您可以在其中捕获at返回的引用:

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

此处std::vector<std::vector<int>> lista = { element1, element2 };,我认为element1向量中有element2lista的副本。

没错。

  

如果我不想创建element1element2的副本,我该怎么做?

如果您不想在外部矢量中存储(副本)矢量,则需要存储其他内容。您不能在容器中存储引用,但可以存储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

答案 3 :(得分:1)

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);