当前位置: 首页 > 知识库问答 >
问题:

如何传播常量时返回一个std::向量从常量方法?

储峻
2023-03-14

让我们在一个示例中展示它,其中我们有一个包含主数据的数据类,某种指向主数据的索引,我们还需要公开索引的const版本。

class Data
{
public:
  const std::vector<int>& getPrimaryData() const { return this->primaryData; }
  const std::vector<int*>& getIndex() const { return this->index; }
private:
  std::vector<int> primaryData;
  std::vector<int*> index;
};

这是错误的,因为用户可以轻松修改数据:

const Data& data = something.getData();
const std::vector<int*>& index = data.getIndex();
*index[0] = 5; // oups we are modifying data of const object, this is wrong

这样做的原因是,Data::getIndex应该返回的正确类型是:

const std::vector<const int*>&

但是,您可以猜测,当您尝试以这种方式编写方法以“将非常量变量转换为常量变量”时会发生什么:

// compiler error, can't convert std::vector<int*> to std::vector<const int*> these are unrelated types.
const std::vector<const int*>& getIndex() const { return this->index; }

据我所知,C没有解决这个问题的好方法。显然,我可以创建新的向量,从索引中复制值并返回它,但从性能角度来看,这没有任何意义。

请注意,这只是更大程序中实际问题的简化示例。int可以是一个更大的对象(比如说Book),而index可以是某种书籍的索引。这些数据可能需要使用索引来修改书籍,但同时,提供索引,以便以恒定的方式阅读书籍。

共有3个答案

夏弘文
2023-03-14

您要求的是d::experimental::propagate_const。但是由于它是一个实验特性,不能保证任何特定的工具链都附带有实现。您可以考虑实现自己的。然而,有一个麻省理工学院许可的实现。在包括标题之后:

using namespace xpr=std::experimental;
///...
std::vector<xpr::propagate_const<int*>> my_ptr_vec;

但是请注意,原始指针被认为是邪恶的,所以您可能需要使用std::unique_ptrstd::shared_ptrpropagate_const应该接受智能指针以及原始指针类型。

贺卜霸
2023-03-14

每种语言都有它的规则和用法d::矢量

对于使用部分,返回完整的容器通常被视为一种糟糕的封装实践,因为它使实现可见,并将其绑定到接口。最好有一个方法获取索引并返回指向const的指针(或者如果需要,返回指向const指针的引用):

const int* getIndex(int i) const { return this->index[i]; }

这是可行的,因为T*可以常量化为const T*

狄旻
2023-03-14

在C 20中,只需返回一个std::span类型为const int*

#include <vector>
#include <span>

class Data
{
public:
  std::span<const int* const> getIndex() const { return this->index; }
private:
  std::vector<int*> index;
};

int main() {
  const Data data;
  const auto index = data.getIndex();
  *index[0] = 5;  // error: assignment of read-only location
}

演示

 类似资料:
  • 本文向大家介绍C++常量详解二(常量形参,常量返回值,常量成员函数),包括了C++常量详解二(常量形参,常量返回值,常量成员函数)的使用技巧和注意事项,需要的朋友参考一下 1.常量形参 当形参有顶层const或者底层const的时候,传给它常量对象或者非常量对象都是可以的,在这里我们主要考虑形参无const, 而实参有const的情况,其实这里也十分简单,只需要记住一点:底层const的限制,就可

  • 本文向大家介绍如何判断一个常量是废弃常量 ?相关面试题,主要包含被问及如何判断一个常量是废弃常量 ?时的应答技巧和注意事项,需要的朋友参考一下 运行时常量池主要回收的是废弃的常量。那么,我们如何判断一个常量是废弃常量呢? 假如在常量池中存在字符串 "abc",如果当前没有任何 String 对象引用该字符串常量的话,就说明常量 "abc" 就是废弃常量,如果这时发生内存回收的话而且有必要的话,"a

  • 本文向大家介绍C++ 常量成员常量返回值详解,包括了C++ 常量成员常量返回值详解的使用技巧和注意事项,需要的朋友参考一下 总结: 1.常量数据成员,形式:const Type m_tData; 1)常量数据成员,需要在构造函数列表中给出,构造函数中可以用常量赋值,也可以实例化的时候赋值。 2)赋值函数中不能赋值,起到保护常量数据成员的作用,和友元作用相反。 2.常量成员函数,形式:type fu

  • 两者之间有实际区别吗 和 ? 看起来包含常量元素的非常量数组仍然无法交换,赋值运算符也不起作用<我什么时候应该选择一个而不是另一个?

  • 我有一个带有私有属性的类,它是一个向量。做getter函数的最佳方法是什么? 返回整个向量:

  • 我有一个整数向量: 考虑到将始终为偶数。 我只是想把相邻的元素转换成一对,像这样: i、 两个相邻的元件连接成一对。 我可以使用什么STL算法轻松实现这一点?有没有可能通过一些标准算法来实现这一点? 当然,我可以很容易地编写一个旧的索引for循环来实现这一点。但我想知道,使用基于范围的for循环或任何其他STL算法(如等)最简单的解决方案是什么样的。