通过带有常量内容的向量

时间:2019-06-07 07:17:17

标签: c++ const

我有一个像这样的向量。

std::vector<std::pair<int,int> > v;

我想将其传递给函数并使之恒定。

我第一次尝试

void fun(const std::vector<std::pair<int,int> > v)

但是该功能使我可以排线

std::pair<int,int> p = v[i];

由于对不是const类型,因此我认为应该抛出错误。然后我意识到,只有指针在vector中被声明为常量,所以我尝试了

void fun(const std::vector<const std::pair<int,int> > v)

但这会引发关于没有转换的错误。

我确定有些内部工作方式我不了解,这使这种做法不合法,但会喜欢一些见识。谢谢。

2 个答案:

答案 0 :(得分:4)

我认为您在这里混淆了引用和值语义。让您测试的第一个功能签名:

void fun(const std::vector<std::pair<int,int> > v)

这会将函数参数复制到另外v限定的新对象const中。这样的签名很少有意义:要么您想将其作为const引用传递(以避免复制),要么希望通过非const值传递,因为函数体将对参数进行突变,但应仅对其副本进行操作。此外,此代码段:

std::pair<int,int> p = v[i];

用上面的函数签名编译就好了,因为它可以将位置i的向量元素复制到新的pair对象中。后者可以突变,但这根本不影响向量。

现在让我们考虑第二个函数签名:

void fun(const std::vector<const std::pair<int,int> > v)

此处仍然适用与以前相同的内容,此外,std::vector<const T>无效,请参见this thread进行解释。


如何解决?如果不想复制参数,但是函数没有修改向量,请通过const引用将其传递。如果函数修改了向量,并且这些修改在调用端可见,则将其作为非const引用传递。如果函数修改了引导程序,但该操作将独立于调用方引导程序而发生,请传递非const值。

答案 1 :(得分:1)

void fun(const std::vector<std::pair<int,int> > v)
{
   ////
   std::pair<int,int> p = v[i];
}

https://en.cppreference.com/w/cpp/container/vector/operator_at

这里不会发生错误,因为const和非const实例的std :: vector都已operator[]重载。在您的情况下,它将解析为const版本,并将const &返回到基础i元素。
考虑以下代码:

void fun(const std::vector<std::pair<int,int> > v)
{
   ////
   std::pair<int,int> p = v[i]; //OK
   v[i] = std::pair<int,int>{10,20}; //Compile error, trying to modify const data!
}