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

std::list<const SomeClass> can not be defined

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

#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;
}

当我从 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
       ^~~~~~~

有什么方法可以定义 std::list 个 const 对象

std::list 必须具有非常量、非易失性 value_type.

错误信息似乎很清楚https://gcc.godbolt.org/z/MG3Kxv:

error: static assertion failed: std::list must have a non-const, non-volatile value_type

分配器感知容器,例如std::list,不能采用const值类型,因为Allocator requirements仅为[指定行为=34=]cv-unqualified 类型。这意味着如果值类型为 constvolatile 合格,则容器不能保证能够通过分配器接口创建元素对象。

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

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

从技术上讲,有人可以 const_cast 远离这种引用的 constness 能够修改元素,这可能是合法的,即不是未定义的行为,但这是一个用户总是可以这样做,只是它会导致 const 个对象出现未定义的行为。

有关详细信息,另请参阅 Does C++11 allow vector<const T>?