std::list<const SomeClass> 无法定义

Ore*_*lom 0 c++ constants stdlist

我正在尝试定义一个常量对象的常量列表,但似乎无法完成。这是我编译良好的示例:

#include <string>
#include <list>

class Person { public:
    std::string name;
    Person(const std::string &in_name){name=in_name;}
};

class MyClass { public:
    const std::list</* const */Person> l;
    MyClass(const std::list</* const */Person> &in_l):l(in_l){}
};

int main(int argc, char **argv) {
    Person dave("dave");
    MyClass c(std::list<const Person>(dave));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我从这const两个地方删除评论时,出现以下错误:

In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
                 from /usr/include/c++/7/bits/allocator.h:46,
                 from /usr/include/c++/7/string:41,
                 from main66.cpp:1:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘class __gnu_cxx::new_allocator<const Person>’:
/usr/include/c++/7/bits/allocator.h:108:11:   required from ‘class std::allocator<const Person>’
main66.cpp:11:53:   required from here
/usr/include/c++/7/ext/new_allocator.h:93:7: error: ‘const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = const Person; __gnu_cxx::new_allocator<_Tp>::const_pointer = const Person*; __gnu_cxx::new_allocator<_Tp>::const_reference = const Person&]’ cannot be overloaded
       address(const_reference __x) const _GLIBCXX_NOEXCEPT
       ^~~~~~~
/usr/include/c++/7/ext/new_allocator.h:89:7: error: with ‘_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = const Person; __gnu_cxx::new_allocator<_Tp>::pointer = const Person*; __gnu_cxx::new_allocator<_Tp>::reference = const Person&]’
       address(reference __x) const _GLIBCXX_NOEXCEPT
       ^~~~~~~
Run Code Online (Sandbox Code Playgroud)

有没有办法定义 const 对象的 std::list

wal*_*nut 8

Allocator-aware 容器,例如std::list,不能接受const值类型,因为Allocator要求只为cv-unqualified类型指定行为。这意味着如果值类型是constvolatile限定的,则不能保证容器能够通过分配器接口创建元素对象。

不过这不是问题,因为容器const足以保证元素不会改变。如果您通过对容器的const引用访问容器的元素,您将永远只能获得const对该元素的引用。

因此,只需使用const std::list<Person>, 而不是const std::list<const Person>

技术上有人可能会const_castconst尼斯从这样的参考客场能够修改的元素,并且很可能是合法的,即不是不确定的行为,但是那是后话,用户可以随时做,只是因为这会引起未定义行为const的对象。

另请参见C++11 是否允许 vector<const T>?详情。