const int *
和int *const
非常不同。与const std::auto_ptr<int>
与std::auto_ptr<const int>
类似。但是,似乎没有const std::vector<int>
与std::vector<const int>
的区别(实际上我不确定第二个是否允许)。这是为什么?
有时我有一个函数,我想传递一个向量的引用。该函数不应该修改向量本身(例如,没有push_back()
),但是它想要修改每个包含的值(比如增加它们)。类似地,我可能想要一个函数只改变矢量结构但不修改它的任何现有内容(尽管这很奇怪)。使用std::auto_ptr
(例如)可以做这种事情,但因为std::vector::front()
(例如)被定义为
const T &front() const;
T &front();
而不仅仅是
T &front() const;
没有办法表达这一点。
我想做的例子:
//create a (non-modifiable) auto_ptr containing a (modifiable) int
const std::auto_ptr<int> a(new int(3));
//this works and makes sense - changing the value pointed to, not the pointer itself
*a = 4;
//this is an error, as it should be
a.reset();
//create a (non-modifiable) vector containing a (modifiable) int
const std::vector<int> v(1, 3);
//this makes sense to me but doesn't work - trying to change the value in the vector, not the vector itself
v.front() = 4;
//this is an error, as it should be
v.clear();
答案 0 :(得分:7)
这是一个设计决定。
如果你有一个const
容器,通常你不希望任何人修改它所包含的元素,这是它的一个固有部分。如果你愿意的话,容器完全“拥有”这些元素“巩固了联系”。
这与历史上更低级别的“容器”实现(即原始阵列)形成鲜明对比,后者更为放手。正如您所说,int const*
和int * const
之间存在很大差异。但标准容器只是选择传递const
。
答案 1 :(得分:4)
区别在于指向int的指针不拥有它们指向的整数,而vector<int>
确实拥有包含的整数。可以将vector<int>
概念化为具有int成员的结构,其中成员的数量恰好是可变的。
如果你想创建一个可以修改向量中包含的值而不是向量本身的函数,那么你应该设计函数来接受迭代器参数。
示例:
void setAllToOne(std::vector<int>::iterator begin, std::vector<int>::iterator end)
{
std::for_each(begin, end, [](int& elem) { elem = 1; });
}
如果您能够将所需的功能放在标题中,那么它可以通用为:
template<typename OutputIterator>
void setAllToOne(OutputIterator begin, OutputIterator end)
{
typedef typename iterator_traits<OutputIterator>::reference ref;
std::for_each(begin, end, [](ref elem) { elem = 1; });
}
答案 2 :(得分:1)
与你的建议语法相关的一个大问题是:std::vector<const T>
与std::vector<T>
的类型不同。因此,如果没有某种转换,您无法将vector<T>
传递给期望vector<const T>
的函数。不是简单的演员,而是创建新的vector<const T>
。那个新的不能简单地与旧的分享数据;它必须将数据从旧数据复制或移动到新数据。
您可以使用std::shared_ptr
来解决此问题,但那是因为这些是共享指针。您可以有两个引用相同指针的对象,因此从std::shared_ptr<T>
到shared_ptr<const T>
的转换不会受到影响(除了引用引用计数之外)。没有shared_vector
。
std::unique_ptr
也有效,因为它们只能被移动,而不能复制。因此,只有其中一个会有指针。
所以你所要求的根本不可能。
答案 3 :(得分:1)