Opened 14 years ago
Closed 14 years ago
#2472 closed Bugs (fixed)
ptr_sequence_adapter<T>::sort fails to compile if T is an abstract base class
| Reported by: | anonymous | Owned by: | Thorsten Ottosen | 
|---|---|---|---|
| Milestone: | Boost 1.38.0 | Component: | ptr_container | 
| Version: | Boost 1.36.0 | Severity: | Problem | 
| Keywords: | Cc: | 
Description
When calling ptr_vector<T>::sort, where T is an abstract base class I get the following compilation error, on MSVC++2008:
error C2027: use of undefined type 'boost::result_of<F>' 1> with 1> [ 1> F=MyFunctorName(T,T) 1> ]
By making T a non-abstract base class (even though there should never be an element of type T in the container) the code compiles and runs as expected; therefore I believe I'm not missing any header files, nor is my compare functor faulted, so it might be a bug on the library.
Change History (3)
comment:1 by , 14 years ago
comment:2 by , 14 years ago
Some more information. It seems that the problem resides with boost::result_of<F> being called as boost::result_of<F(AbstractType, AbstractType)>, even though F takes AbstractType& as argument. This doesn't compile in Microsoft Visual C++ 2008, though it has been said to work in some other compilers.
comment:3 by , 14 years ago
| Resolution: | → fixed | 
|---|---|
| Status: | new → closed | 


Okay, so this isn't a problem with ptr_container per-se but rather a bug with MSVC, which might also manifest itself in other parts of the library. I'm posting a workaround that should fix the problem, but I still believe it should be taken into account and fixed in a future release.
// --------------------------------------------------------------------------------------- // Fix for a bug in MSVC++ that made sort fail on ptr_containers which held pointers // to abstract types. Include and use sort_ptr_container(ptr_container [, function]). // Thanks goes to Dodheim who originally came up with this fix :-) // --------------------------------------------------------------------------------------- #include <algorithm> #include <boost/type_traits/remove_pointer.hpp> template<typename Fun, typename Arg> class indirect_compare { private: Fun fun; public: typedef bool result_type; indirect_compare() : fun(Fun()) {} indirect_compare(Fun f) : fun(f) {} result_type operator ()(const void* lhs, const void* rhs) const { return fun(*static_cast<const Arg*>(lhs), *static_cast<const Arg*>(rhs)); } }; template<typename container_t> void sort_ptr_container(container_t& container) { typedef typename boost::remove_pointer<typename container_t::value_type>::type Arg; sort_ptr_container(container, std::less<Arg>()); } template<typename container_t, typename Fun> void sort_ptr_container(container_t& container, Fun f) { typedef typename boost::remove_pointer<typename container_t::value_type>::type Arg; std::sort(container.begin().base(), container.end().base(), indirect_compare<Fun, Arg>(f)); }