Compilation errors - std :: set with const members

I canโ€™t understand for life what happened to this code:

ClassA & doSomething (std::set<boost::shared_ptr<ClassB const> const > const & someSet) { std::set<boost::shared_ptr<ClassB> > secondSet; for (std::set<boost::shared_ptr<ClassB const> const >::const_iterator it = someSet.begin(); it != someSet.end(); it++) { if (checkSomething(*it)) secondSet.insert(boost::const_pointer_cast<ClassB>(*it)); } } 

When I try to compile, I get the following errors in line 4 (beginning of the for loop) from g ++:

 /usr/include/c++/4.4/ext/new_allocator.h:79: error: 'const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const [with _Tp = const boost::shared_ptr<const ClassB>]' cannot be overloaded /usr/include/c++/4.4/ext/new_allocator.h:76: error: with '_Tp* __gnu_cxx::new_allocator<_Tp>::address(_Tp&) const [with _Tp = const boost::shared_ptr<const ClassB>]' 

If I modify the std::set declaration to contain a non-constant boost::shared_ptr , the code compiles fine, but that means that I can not ensure const-correctness matches in my code.

Does anyone have any ideas as to what might cause these errors? I searched both Google and StackOverflow with no luck.

The following is a minimal (non) working example:

 #include <set> #include <boost/shared_ptr.hpp> class ClassB; class ClassA { public: ClassA & doSomething (std::set<boost::shared_ptr<ClassB const> const > const & someSet); }; ClassA & doSomething (std::set<boost::shared_ptr<ClassB const> const > const & someSet) { std::set<boost::shared_ptr<ClassB> > secondSet; for (std::set<boost::shared_ptr<ClassB const> const >::const_iterator it = someSet.begin(); it != someSet.end(); it++) { if (checkSomething(*it)) secondSet.insert(boost::const_pointer_cast<ClassB>(*it)); } return (*this); } 
+4
source share
3 answers

but that means that I cannot provide const-correctness in my code

I think you might be wrong. As long as it is a smart pointer to a const object, you can manipulate pointers in a set, not objects. It is a kind of whole because a set cannot organize itself if it cannot touch values.

This is the classic difference between

 const char* x; // pointer to const char const char* const x; // constant pointer to const char char* const x; // constant pointer, to non-const char 

Only this time using smartpointers. You can also see for yourself that this simple test will not run for const objects:

 #include <set> int main() { std::set<const int> a; a.insert(1); return 1; } 

Once you remove the 'const', it will work.


OT: If you want some kind of โ€œkeyโ€ protection in some container, you should probably look at the map, because in value_type (std :: pair) the key (.first) is always const - IIRC. I still believe that the point is controversial regarding the const-correctness of the container elements.

+6
source

ยง23.1 / 3 states that the key types std::set must be assignable and copy constructive; obviously, the const type will not be assigned.

+5
source

I have an incentive to try, but I think you should const ClassB, but not shared_ptr, try removing the middle const (on shared_ptr).

0
source

Source: https://habr.com/ru/post/1346385/


All Articles