的std ::设置<INT * const的>不会编译

问题描述 投票:7回答:3

这里的“常量”是编制问题的原因。然而,已经实施了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;
}

而这里的错误:

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

是否有一个“干净”的方式来做到这一点? (也就是不工作,周围像制作“指针类”用一个比较像这样每一种情况)

c++ pointers const stdset
3个回答
9
投票

您不能修改存储在std::set这样的点是没有实际意义的元素。它的目的是保持在一个有序和修改将打破保障要素。这就是为什么迭代器(包括std::set<T>::iteratorstd::set<T>::const_iteratorboth return const references

有没有办法来编辑mutable(或const_cast)的元素短,在这种情况下,你仍然需要保证顺序保持不变。


3
投票

这里有一个简单的程序来证明你所看到的问题:

int main(int argc, char ** argv)
{
   int * const a = NULL;
   int * const b = NULL;

   b = a;   // error: cannot assign to variable 'b' with const-qualified type
}

请注意,这是一个编译时错误改变int * const的变量的值,因为变量被认为是只读的。

std::set内部有同样的问题 - 它需要修改指定类型的变量,它不能这样做,如果是只读的,其指定的类型。

更改为const int *而不是类型可能是你想要做什么,因为这类型允许指针被覆盖在必要时(同时不允许修改的ints它们指向)。


1
投票

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

一组满足所有的容器的要求,一个可逆容器([container.requirements]),缔合容器([associative.reqmts]),以及一个分配器感知容器(表65)的。

在[allocator.requirements]在table 33你可以阅读:

T, U, C any cv-unqualified object type ([basic.types])

其中T是相同X :: VALUE_TYPE其中X是an allocator class for type T。这意味着std::allocator<int * const>不符合上述要求。

这是真实的许多其他容器,例如向量,你可以在这里阅读更多:Does C++11 allow vector<const T>?

[编辑[

Visual Studio中提供了更具描述性的错误:

C:\ Program Files文件(x86)的\微软的Visual Studio 14.0 \ VC \ INCLUDE \ xmemory0(585):错误C2338:因为形成不良的分配器C ++标准不允许使用const元素的容器。

铿锵您可能会看到第一个错误线引导到分配器头:

../include/c++/5.5.0/ext/new_allocator.h:93:7:错误: '地址' 实例相同的签名“__gnu_cxx :: new_allocator :: const_pointer(__gnu_cxx :: new_allocator ::的为const_reference多个重载)const的noexcept”(又名 'INT * const的*(INT * const的&)常量noexcept')地址(为const_reference __X)........

© www.soinside.com 2019 - 2024. All rights reserved.