I can't for the life of me figure out what's wrong with 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 at line 4 (the start 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 change the std::set
declaration to contain non-const boost::shared_ptr
the code compiles perfectly, but that mean I won't be able to enforce const-correctness in my code.
Has anyone got any idea as to what might be causing these errors? I've searched both Google & StackOverflow without any luck.
Here is a minimum (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);
}
but that mean I won't be able to enforce const-correctness in my code
I think you may be wrong there. As long it is a smart pointer to a const object, you may only manipulate the pointers in the set, not the objects referred to. This is kind of the whole point, because a set cannot organize itself if it cannot touch the values.
It's the classical 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 with smartpointers. You can also verify for yourself that this simple test will fail for const items:
#include <set>
int main()
{
std::set<const int> a;
a.insert(1);
return 1;
}
Once you remove 'const' it will work.
OT: If you want some container that has some kind of 'key' protection, you should perhaps look at map since in the value_type (std::pair) the key (.first) is always const - IIRC. I still think the point is moot with regard to const correctness of the container's elements.
§23.1/3 states that std::set
key types must be assignable and copy constructable; clearly a const type will not be assignable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With