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 annonymous, 14 years ago

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));
}

comment:2 by anonymous, 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 Thorsten Ottosen, 14 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.