1

I have a Visual Studio 2008 C++03 application using boost 1.47 phoenix (Update: also with 1.49). I would like to define a boost::function to remove an element from a list. For example:

#include <boost/phoenix.hpp>
#include <boost/function.hpp>
#include <boost/phoenix/stl/container.hpp>
#include <boost/phoenix/stl/algorithm/transformation.hpp>
#include <algorithm>    
#include <list>

int main()
{
    namespace bp = boost::phoenix;
    namespace bpa = boost::phoenix::arg_names;
    std::list< int > a;
    boost::function< void( int ) > RemoveFromList = bp::remove( bp::ref( a ), bpa::arg1 );
    return 0;
}

but I get a series of compiler errors on my RemoveFromList definition.

Error  1  error C2504: 'boost::phoenix::impl::remove::result<Sig>' : base class undefined  \boost\utility\result_of.hpp  80
Error  2  error C2039: 'type' : is not a member of 'boost::result_of<F>'  \boost\phoenix\core\detail\preprocessed\function_eval_10.hpp  121
Error  3  error C2146: syntax error : missing ';' before identifier 'type'  \boost\phoenix\core\detail\preprocessed\function_eval_10.hpp  122
Error  4  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int  \boost\phoenix\core\detail\preprocessed\function_eval_10.hpp  122
Error  5  error C2602: 'boost::phoenix::detail::function_eval::result<Sig>::type' is not a member of a base class of 'boost::phoenix::detail::function_eval::result<Sig>'  \boost\phoenix\core\detail\preprocessed\function_eval_10.hpp  122
Error  6  error C2868: 'boost::phoenix::detail::function_eval::result<Sig>::type' : illegal syntax for using-declaration; expected qualified-name  \boost\phoenix\core\detail\preprocessed\function_eval_10.hpp  122

A similar function AddToList compiles cleanly:

boost::function< void( int ) > AddToList = bp::push_back( bp::ref( a ), bpa::arg1 );

This also works correctly (but is much less elegant):

boost::function< void( int ) > RemoveFromList = bp::bind( &std::remove< std::list< int >::iterator, int >, a.begin(), a.end(), bpa::arg1 );

What is the correct way to implement this function?

Thanks

PaulH
  • 7,759
  • 8
  • 66
  • 143

1 Answers1

1

Using Boost 1.48 your snippet compiles with GCC 4.7 provided I have the right includes and, crucially, provided that the macro BOOST_RESULT_OF_USE_DECLTYPE is defined. Without the latter, it fails.

No idea how to fix this without C++11.

Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • I've updated the question with the includes I'm using. Can you verify we're using the same ones? – PaulH Jun 12 '12 at 13:53
  • Okay, thanks. I've posted this to the boost.user's mailing list. It turns out that I can use any of the algorithms that return a fixed type (like void). If they return a dependent type, then there's some boost::result_of trickery that goes on and that's what's failing. It may be that these are only supported by C++11 compilers. – PaulH Jun 13 '12 at 14:28
  • @PaulH To clarify what the macro does is that `boost::result_of` will defer to `decltype` instead of using what is usually called the Boost.ResultOf protocol (which does make use of dependent types). Not using the macro fails to compile *even in C++11 mode*. What's C++11 specific is `decltype`, i.e. can't use that macro in C++03 mode. – Luc Danton Jun 13 '12 at 19:20
  • So, it sounds like there's an issue with Phoenix's use of the Boost.ResultOf library or an issue with the Visual Studio compiler interpreting the Boost.ResultOf library. – PaulH Jun 14 '12 at 13:37
  • @PaulH FWIW the errors I faced also pointed to `boost::result_of`, using GCC. – Luc Danton Jun 14 '12 at 19:57