std :: set <int*const>不会编译

Ell*_*ith 7 c++ pointers const stdset

这里的"const"是编译问题的原因.但是,自己实现了STL树,我无法理解为什么.

这是代码:

#include <iostream>
#include <set>

int main ()
{
    int a;

    // I want the set to carry the "promise"
    // to keep the pointers constant
    std :: set < int * const > x;

    x . insert ( &a );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是错误:

In file included from /usr/include/c++/7/string:48:0,
                 from /usr/include/c++/7/bits/locale_classes.h:40,
                 from /usr/include/c++/7/bits/ios_base.h:41,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from demo.cpp:1:
/usr/include/c++/7/bits/stl_function.h: In instantiation of ‘struct std::_Identity<int* const>’:
/usr/include/c++/7/bits/stl_tree.h:2091:29:   required from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = int* const; _Key = int* const; _Val = int* const; _KeyOfValue = std::_Identity<int* const>; _Compare = std::less<int* const>; _Alloc = std::allocator<int* const>]’
/usr/include/c++/7/bits/stl_set.h:510:48:   required from ‘std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::value_type&&) [with _Key = int* const; _Compare = std::less<int* const>; _Alloc = std::allocator<int* const>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<int* const>; std::set<_Key, _Compare, _Alloc>::value_type = int* const]’
demo.cpp:11:18:   required from here
/usr/include/c++/7/bits/stl_function.h:877:7: error: ‘const _Tp& std::_Identity<_Tp>::operator()(const _Tp&) const [with _Tp = int* const]’ cannot be overloaded
       operator()(const _Tp& __x) const
       ^~~~~~~~
/usr/include/c++/7/bits/stl_function.h:873:7: error: with ‘_Tp& std::_Identity<_Tp>::operator()(_Tp&) const [with _Tp = int* const]’
       operator()(_Tp& __x) const
Run Code Online (Sandbox Code Playgroud)

这样做有"干净"的方法吗?(也就是说,不是像在这样的每种情况下使用比较器制作"指针类"的解决方法)

kmd*_*eko 9

你不能修改存储在一个元素,std::set所以这一点是没有实际意义的.它旨在使元素保持排序顺序,修改将破坏该保证.这就是迭代器(both std::set<T>::iteratorstd::set<T>::const_iterator)都返回const引用的原因.

无法编辑mutable(或const_cast)之外的元素,在这种情况下,您仍需要保证顺序保持不变.


mar*_*inj 2

更正式的答案是std::set满足AllocatorAwareContainer的要求:

集合满足容器、可逆容器([container.requirements])、关联容器([associative.reqmts])和分配器感知容器(表 65)的所有要求。

表 33的 [allocator.requirements] 中,您可以看到:

T, U, C any cv-unqualified object type ([basic.types])
Run Code Online (Sandbox Code Playgroud)

其中 T 与 X::value_type 相同,其中 X 是an allocator class for type T。这意味着std::allocator<int * const>不满足上述要求。

对于许多其他容器来说也是如此,例如向量,您可以在此处阅读更多内容:Does C++11 allowed vector<const T>?

[编辑[

Visual Studio 给出了稍微更具描述性的错误:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\xmemory0(585): 错误 C2338: C++ 标准禁止 const 元素的容器,因为分配器格式不正确。

使用 clang,您可能会看到第一个错误行指向分配器标头:

../include/c++/5.5.0/ext/new_allocator.h:93:7:错误:'address'的多个重载实例化为相同的签名'__gnu_cxx::new_allocator::const_pointer (__gnu_cxx::new_allocator::const_reference ) const noexcept' (又名 'int *const *(int *const &) const noexcept') 地址(const_reference __x) ........