C++ 给出编译错误的常量对象向量

C++ 给出编译错误的常量对象向量,c++,stdvector,c++98,C++,Stdvector,C++98,我在代码中声明了以下内容 vector <const A> mylist; 向量mylist; 我得到以下编译错误- new_allocator.h:75: error: `const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const \[with _Tp = const A]' and `_Tp* __gnu_cxx::new_allocator<_Tp>::addres

我在代码中声明了以下内容

vector <const A> mylist; 
向量mylist;
我得到以下编译错误-

new_allocator.h:75: error: `const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const \[with _Tp = const A]' and `_Tp* __gnu_cxx::new_allocator<_Tp>::address(_Tp&) const [with _Tp = const A]' cannot be overloaded
new\u allocator.h:75:错误:`const\u Tp*\uu gnu\u cxx::new\u allocator::address(const\u Tp&)const\[with _Tp=const A]'和`u Tp*\u gnu cxx::new\u allocator::address(_Tp&)const[with _Tp=const A]'不能重载
但如宣布—

vector <A> mylist;
向量mylist;
我的代码可以编译

在此上下文中是否不允许常量

我在这里复制我的代码供大家参考-

#include <iostream>
#include <vector>

using namespace std;
class A
{
public:
    A () {cout << "default constructor\n";}
    A (int i): m(i) {cout << "non-default constructor\n";}

private:
    int m;
};

int main (void)
{
    vector<const A> mylist;

    mylist.push_back(1);

    return 0;
}
#包括
#包括
使用名称空间std;
甲级
{
公众:

向量中的({cout项必须是可分配的(或者,在标准的较新版本中是可移动的)。
const
对象是不可分配的,因此尝试将它们存储在向量中将失败(或者至少可以失败——代码是无效的,但是编译器可以自由地接受它,如果它选择的话,尽管大多数程序员通常希望拒绝无效代码)

我想对于真正的学究来说,如果你非常想,你可以定义一个类型,尽管它是
const
,但它是可赋值的,类似这样:

class ugly { 
    mutable int x;
public:
    ugly const &operator=(ugly const &u) const { 
        x = u.x;
        return *this;
    }
};
我相信您应该能够将这种类型的项存储在
向量中,即使它们是
const
。VC++成功地实现了创建这些项的向量的快速测试。这在一些较旧的编译器中失败(例如,g++4.8.1失败),但在较新的编译器中可以正常工作(VC++至少可以追溯到2015年,g++至少可以追溯到5.4版,而clang++至少可以追溯到4.0版——尽管我还没有找到支持它的每个版本的第一个版本)


对于当前的编译器,支持移动
const
对象的类型可能也可以。但是,以防万一,这并不明显:这允许您修改对象,即使它标记为
const
。这显然直接违反了任何合理的用户期望,因此这主要是一个问题,而不是解决方案离子。

使用
push\u-back
方法是个问题。
emplace\u-back
将编译。 另一种选择(取决于此处未描述的整个情况)是,如果插入的项目的寿命超出向量,则使用
向量。
向量中的项不需要可赋值,但当它们不可赋值时,某些成员函数和算法就不能使用

说明:

push_back
应该首先在向量中默认构造一个A,然后分配(使用复制构造)给定的引用。这会破坏您的
const
限定,因此不会编译


emplace\u back
使用“完美转发”直接调用实际的构造函数。

您使用的编译器是什么?这对我来说很好。您希望用const items实现什么?@petric-我用g++(GCC)编译了它3.4.3可能重复使用gcc 3.4.3编译的@underline\u d:不是c++11。实际上,您可以在不可赋值项上使用向量。只是您不能使用很多成员函数/算法,例如push\u back。@lip:在某些情况下,您可能可以不使用它,但我相信在任何情况下,标准中的要求都是MoveAssignable或CopySignable。我们刚刚遇到了同样的问题。代码在VC++(2012)中编译并运行良好,但g++4.8.2和clang 3.4都不喜欢它。C++03中的“向量中的项必须是可分配的”;对于C++11,这一要求有所放宽。(但是,C++11上是否允许使用
const
对象的向量尚不完全清楚;请参阅)
const
-变量的性质意味着变量一旦赋值就不能更改。因此,我不明白:为什么人们永远不想将向量中永远不应该更改的对象放入向量中?我也不明白为什么push_back不起作用。通常正确,但
emplace_back
不使用对象的move构造函数。它使用“完美转发”直接调用实际的构造函数。参见(例如)我认为容器也不允许存储引用(或者至少不允许
向量
向量
不编译器容器不能存储引用。这到底是怎么得到7票的?