Compiler craziness on boost::result_of ? Please help

I'm using Visual Studio 10, and Boost 1.49. The following complete CPP file compiles without error: ===== #include <boost/test/unit_test.hpp> #include "boost/thread/future.hpp" #include <boost/utility/result_of.hpp> #include <functional> using boost::unique_future; template <typename F> unique_future<typename boost::result_of< F() >::type> foo (F&& f) { typedef typename boost::result_of< F() >::type RetType; unique_future<RetType> future_result; return std::move(future_result); } template <typename F, typename A1> unique_future<typename boost::result_of< F(A1) >::type> foo (F&& f, A1&& a1) { return std::move(foo (std::tr1::bind(f,a1))); } class C {}; class D : public C { public: void mf() const { } // virtual void toxic() { } }; void mainfunc() { D* p; foo (&D::mf, p); } ===== But, if you un-comment the definition of toxic, then it will not compile, giving instead: 1>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2825: 'F': must be a class or namespace when followed by '::' 1> E:\boost_1_49\boost/utility/result_of.hpp(90) : see reference to class template instantiation 'boost::detail::result_of_nested_result<F,FArgs>' being compiled 1> with 1> [ 1> F=void (__thiscall D::* &)(void) const, 1> FArgs=void (__thiscall D::* &(D *&))(void) const 1> ] 1> E:\boost_1_49\boost/utility/detail/result_of_iterate.hpp(33) : see reference to class template instantiation 'boost::detail::tr1_result_of_impl<F,FArgs,HasResultType>' being compiled 1> with 1> [ 1> F=void (__thiscall D::* &)(void) const, 1> FArgs=void (__thiscall D::* &(D *&))(void) const, 1> HasResultType=false 1> ] 1> E:\boost_1_49\boost/utility/detail/result_of_iterate.hpp(75) : see reference to class template instantiation 'boost::tr1_result_of<F>' being compiled 1> with 1> [ 1> F=void (__thiscall D::* &(D *&))(void) const 1> ] 1> threadpoolTest.cpp(39) : see reference to class template instantiation 'boost::result_of<F>' being compiled 1> with 1> [ 1> F=void (__thiscall D::* &(D *&))(void) const 1> ] 1>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2516: 'F' : is not a legal base class 1> E:\boost_1_49\boost/utility/result_of.hpp(90) : see declaration of 'F' 1>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2143: syntax error : missing ',' before '::' 1>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2903: 'result' : symbol is neither a class template nor a function template 1>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2039: 'result' : is not a member of '`global namespace'' 1>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2504: 'result' : base class undefined 1>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2143: syntax error : missing ',' before '<' 1>threadpoolTest.cpp(39): error C2893: Failed to specialize function template 'boost::unique_future<boost::result_of<F(T0)>::type> foo(F &&,A1 &&)' 1> With the following template arguments: 1> 'void (__thiscall D::* &)(void) const' 1> 'D *&' 1>threadpoolTest.cpp(39): error C2780: 'boost::unique_future<boost::result_of<F(void)>::type> foo(F &&)' : expects 1 arguments - 2 provided 1> threadpoolTest.cpp(10) : see declaration of 'foo' 1> 1>Build FAILED. Note that both the presence of a virtual function and a base class in necessary. if toxic is present but C is not, then it still works.

On Fri, Apr 13, 2012 at 8:02 AM, John M. Dlugosz <mpbecey7gu@snkmail.com>wrote:
I'm using Visual Studio 10, and Boost 1.49. The following complete CPP file compiles without error:
I don't have access to VS 10 so...bear with me...
===== #include <boost/test/unit_test.hpp> #include "boost/thread/future.hpp" #include <boost/utility/result_of.hpp> #include <functional>
using boost::unique_future;
template <typename F> unique_future<typename boost::result_of< F() >::type> foo (F&& f) { typedef typename boost::result_of< F() >::type RetType; unique_future<RetType> future_result; return std::move(future_result); }
template <typename F, typename A1> unique_future<typename boost::result_of< F(A1) >::type> foo (F&& f, A1&& a1) { return std::move(foo (std::tr1::bind(f,a1))); }
class C {};
class D : public C { public: void mf() const { } // virtual void toxic() { } };
void mainfunc() {
D* p; foo (&D::mf, p);
}
=====
But, if you un-comment the definition of toxic, then it will not compile, giving instead:
1>E:\boost_1_49\boost/utility/**result_of.hpp(82): error C2825: 'F': must be a class or namespace when followed by '::' 1> E:\boost_1_49\boost/utility/**result_of.hpp(90) : see reference to class template instantiation 'boost::detail::result_of_**nested_result<F,FArgs>' being compiled 1> with 1> [ 1> F=void (__thiscall D::* &)(void) const,
Hmmm...I wonder if the problem is that F is bound to a *reference* to a pointer-to-member. Although then I'm surprised things work without the base class or the virtual member function. Try replacing "F" in your boost::result_of queries with boost::remove_reference<F>::type.
1> FArgs=void (__thiscall D::* &(D *&))(void) const 1> ] 1> E:\boost_1_49\boost/utility/**detail/result_of_iterate.hpp(**33) : see reference to class template instantiation 'boost::detail::tr1_result_of_**impl<F,FArgs,HasResultType>' being compiled 1> with 1> [ 1> F=void (__thiscall D::* &)(void) const, 1> FArgs=void (__thiscall D::* &(D *&))(void) const, 1> HasResultType=false 1> ]
Also, see if changing line 25 in result_of_iterate.hpp (near the reference above) to mpl::or_< is_pointer< typename boost::remove_reference<F>::type
, is_member_function_pointer< typename boost::remove_reference<F>::type > >
from mpl::or_< is_pointer<F>, is_member_function_pointer<F> > helps. 1> E:\boost_1_49\boost/utility/**detail/result_of_iterate.hpp(**75)
: see reference to class template instantiation 'boost::tr1_result_of<F>' being compiled 1> with 1> [ 1> F=void (__thiscall D::* &(D *&))(void) const 1> ] 1> threadpoolTest.cpp(39) : see reference to class template instantiation 'boost::result_of<F>' being compiled 1> with 1> [ 1> F=void (__thiscall D::* &(D *&))(void) const 1> ] 1>E:\boost_1_49\boost/utility/**result_of.hpp(82): error C2516: 'F' : is not a legal base class 1> E:\boost_1_49\boost/utility/**result_of.hpp(90) : see declaration of 'F' 1>E:\boost_1_49\boost/utility/**result_of.hpp(82): error C2143: syntax error : missing ',' before '::' 1>E:\boost_1_49\boost/utility/**result_of.hpp(82): error C2903: 'result' : symbol is neither a class template nor a function template 1>E:\boost_1_49\boost/utility/**result_of.hpp(82): error C2039: 'result' : is not a member of '`global namespace'' 1>E:\boost_1_49\boost/utility/**result_of.hpp(82): error C2504: 'result' : base class undefined 1>E:\boost_1_49\boost/utility/**result_of.hpp(82): error C2143: syntax error : missing ',' before '<' 1>threadpoolTest.cpp(39): error C2893: Failed to specialize function template 'boost::unique_future<boost::**result_of<F(T0)>::type> foo(F &&,A1 &&)' 1> With the following template arguments: 1> 'void (__thiscall D::* &)(void) const' 1> 'D *&' 1>threadpoolTest.cpp(39): error C2780: 'boost::unique_future<boost::**result_of<F(void)>::type> foo(F &&)' : expects 1 arguments - 2 provided 1> threadpoolTest.cpp(10) : see declaration of 'foo' 1> 1>Build FAILED.
Note that both the presence of a virtual function and a base class in necessary. if toxic is present but C is not, then it still works.
Again, this seems mysterious to me... - Jeff
participants (2)
-
Jeffrey Lee Hellrung, Jr.
-
John M. Dlugosz