tr1/function and phoenix

Philipp Reh sefi@s-e-f-i.de
Mon Sep 21 12:30:00 GMT 2009


Hi,

the following code fails with gcc-4.4.1 and phoenix from boost-1.40:

#include <boost/spirit/home/phoenix/core/reference.hpp>
#include <boost/spirit/home/phoenix/operator/self.hpp>
#include <tr1/functional>
#include <iostream>
#include <ostream>

int main()
{
	typedef std::tr1::function<
		void ()
	> function_type;

	bool running = true;

	function_type const fun(
		boost::phoenix::ref(
			running
		) = false
	);

	fun();

	std::cout << running << '\n';
}

The problem is that tr1::function tries to use operator &
on the phoenix object to form a pointer, but phoenix defines operator &
itself.

The error message is as follows:

/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.1/include/g++-v4/tr1_impl/functional:
In static member function 'static _Functor*
std::tr1::_Function_base::_Base_manager<_Functor>::_M_get_pointer(const
std::tr1::_Any_data&) [with _Functor =
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::phoenix::reference<bool>,
boost::phoenix::value<bool>, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >]':
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.1/include/g++-v4/tr1_impl/functional:1668:
instantiated from 'static void
std::tr1::_Function_handler<void(_ArgTypes ...),
_Functor>::_M_invoke(const std::tr1::_Any_data&, _ArgTypes ...) [with
_Functor =
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::phoenix::reference<bool>,
boost::phoenix::value<bool>, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >,
_ArgTypes = ]'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.1/include/g++-v4/tr1_impl/functional:2005:
instantiated from 'std::tr1::function<_Res(_ArgTypes
...)>::function(_Functor, typename __gnu_cxx::__enable_if<(!
std::tr1::is_integral::value), std::tr1::function<_Res(_ArgTypes
...)>::_Useless>::__type) [with _Functor =
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::phoenix::reference<bool>,
boost::phoenix::value<bool>, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >,
_Res = void, _ArgTypes = ]'
test.cpp:19:   instantiated from here
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.1/include/g++-v4/tr1_impl/functional:1490:
error: no match for ternary 'operator?:' in 'false ?
boost::phoenix::operator&(const boost::phoenix::actor<BaseT0>&) [with T0
= boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::phoenix::reference<bool>,
boost::phoenix::value<bool>, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >]() :
((const std::tr1::_Any_data*)__source)->std::tr1::_Any_data::_M_access
[with _Tp =
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::phoenix::reference<bool>,
boost::phoenix::value<bool>, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
>*]()'

As far as I can see, the tr1 working paper doesn't forbid that a functor
defines operator &. I couldn't reproduce the issue with a simpler test
so it might have to do with the fact that the phoenix functor is a temporary
in my test case.

What can I do to workaround this and is this a bug?

Cheers,
Philipp



More information about the Libstdc++ mailing list