boost::ptr_vector does not support const types

I would like to use a ptr_vector to hold a number of const values but it seems ptr_vector does not currently support the use of const value types. See this simple code example: #include "boost/ptr_container/ptr_vector.hpp" #include <vector> class X { const int i; public: X(int i) : i(i) {} int getI() const { return i; } }; int main() { boost::ptr_vector<X> bvx; boost::ptr_vector<const X> bvcx; std::vector<X*> svx; std::vector<const X*> svcx; bvx.push_back(new X(42)); bvcx.push_back(new X(42)); // does not compile svx.push_back(new X(42)); svcx.push_back(new X(42)); return 0; } I have tried this on MSVC 2005/8.0 and with g++ on Mac – i.e. Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn). On both compilers, calling 'push_back()' on a 'boost::ptr_vector<const X>' does not compile and on g++/Mac it yields this error message: ../boost/boost/ptr_container/ptr_sequence_adapter.hpp:249:37: error: reference to type 'const value_type' (aka 'void *const') could not bind to an lvalue of type 'value_type' (aka 'const X *') this->base().push_back( x ); // strong, commit ^ ptr_vector_test.cpp:22:8: note: in instantiation of member function 'boost::ptr_sequence_adapter<const X, std::__1::vector<void *, std::__1::allocator<void *> >, boost::heap_clone_allocator>::push_back' requested here bvcx.push_back(x); ^ /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:697:62: note: passing argument to parameter '__x' here _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x); ^ 1 error generated. So the problem occurs when the passed value of type 'const X*' needs to be pushed to the backing 'std::vector<void*>' – i.e. a non-const 'void*' element type. The same problem exists for push_front(). A simple fix for 'push_back()' (and similar for 'push_front()') is to modify the file 'ptr_sequence_adapter.hpp' adding a cast of the value before pushing is: --- a/include/boost/ptr_container/ptr_sequence_adapter.hpp +++ b/include/boost/ptr_container/ptr_sequence_adapter.hpp @@ -246,7 +246,7 @@ namespace ptr_container_detail this->enforce_null_policy( x, "Null pointer in 'push_back()'" ); auto_type ptr( x ); // notrow - this->base().push_back( x ); // strong, commit + this->base().push_back( (void*) x ); // strong, commit ptr.release(); // nothrow } I am using a C-style cast as neither 'const_cast' nor 'reinterpret_cast' can be used here. (I know the formatting of the comments should also be fixed, but that would make my diff here more difficult to read.) Is there another workaround for this or have I overlooked something? /Martin

On 18-08-2015 09:35, Martin Gamwell Dawids wrote:
Is there another workaround for this or have I overlooked something?
I don't think there is a workaround. There was a fix for this in the old trunk branch, but I don't know if it has been merged to the release branch. regards -Thorsten

Is there another workaround for this or have I overlooked something?
I don't think there is a workaround. There was a fix for this in the old trunk branch, but I don't know if it has been merged to the release branch.
Not being familiar with boost development, could you give me a pointer to the fix in the old trunk branch? Then I could have a look in the git repo to see if the fix exists there or otherwise create a pull request. Regards, Martin

On 24-08-2015 14:37, Martin Gamwell Dawids wrote:
Is there another workaround for this or have I overlooked something?
I don't think there is a workaround. There was a fix for this in the old trunk branch, but I don't know if it has been merged to the release branch.
Not being familiar with boost development, could you give me a pointer to the fix in the old trunk branch? Then I could have a look in the git repo to see if the fix exists there or otherwise create a pull request.
I think it was a bunch of const_cast internally. regards -Thorsten
participants (2)
-
Martin Gamwell Dawids
-
Thorsten Ottosen