
Consider these functions: template <typename F> unique_future<typename boost::result_of< F() >::type> foo (F&& f) { ⋯ template <typename F, typename A1> unique_future<typename boost::result_of< F(A1) >::type> foo (F&& f, A1&& a1) { return foo (std::tr1::bind(f,a1)); } I can call foo(&bar,5) to mean the same thing as foo(bind(&bar,5)), OK. But I cannot call foo(&C::mf, pc) to mean the same as foo(bind(&C::mf,pc)) when the binding in question is pc->mf(). That is, bind treats a member function automatically as a function whose first argument is 'this', but boost::result_of does not have the same trick. How can I express the result type of the second form of foo shown above? —John

The plot thickens: class Universe : std::tr1::enable_shared_from_this<Universe> { const int answer; public: Universe (int a) : answer(a) {} std::string get_answer() const; void get_nothing() {} virtual void blahblah(); // !!! }; Universe u1(42); foo (&Universe::get_answer, &u1); Regarding my previous post on the definitions of foo, if the class inherits from enable_shared_from this *and* contains a virtual function, then this call to foo doesn't work, giving funny template errors in boost::result_of. 2>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2825: 'F': must be a class or namespace when followed by '::' 2> 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 2> with 2> [ 2> F=std::basic_string<char,std::char_traits<char>,std::allocator<char>> (__thiscall thread_pool_tests::Universe::* &)(void) const, 2> FArgs=std::basic_string<char,std::char_traits<char>,std::allocator<char>> (__thiscall thread_pool_tests::Universe::* &(thread_pool_tests::Universe *))(void) const 2> ] 2> 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 2> with 2> [ 2> F=std::basic_string<char,std::char_traits<char>,std::allocator<char>> (__thiscall thread_pool_tests::Universe::* &)(void) const, 2> FArgs=std::basic_string<char,std::char_traits<char>,std::allocator<char>> (__thiscall thread_pool_tests::Universe::* &(thread_pool_tests::Universe *))(void) const, 2> HasResultType=false 2> ] 2> 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 2> with 2> [ 2> F=std::basic_string<char,std::char_traits<char>,std::allocator<char>> (__thiscall thread_pool_tests::Universe::* &(thread_pool_tests::Universe *))(void) const 2> ] 2> threadpoolTest.cpp(78) : see reference to class template instantiation 'boost::result_of<F>' being compiled 2> with 2> [ 2> F=std::string (__thiscall thread_pool_tests::Universe::* &(thread_pool_tests::Universe *))(void) const 2> ] 2>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2516: 'F' : is not a legal base class 2> E:\boost_1_49\boost/utility/result_of.hpp(90) : see declaration of 'F' 2>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2143: syntax error : missing ',' before '::' 2>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2903: 'result' : symbol is neither a class template nor a function template 2>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2039: 'result' : is not a member of '`global namespace'' 2>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2504: 'result' : base class undefined 2>E:\boost_1_49\boost/utility/result_of.hpp(82): error C2143: syntax error : missing ',' before '<' 2>threadpoolTest.cpp(78): error C2780: 'boost::unique_future<boost::result_of<F(T0,T1)>::type> foo(F &&,A1 &&,A2 &&)' : expects 3 arguments - 2 provided 2> V⋯.h(243) : see declaration of 'vst::async' 2>threadpoolTest.cpp(78): error C2893: Failed to specialize function template 'boost::unique_future<boost::result_of<F(T0)>::type> vst::async(F &&,A1 &&)' 2> With the following template arguments: 2> 'std::string (__thiscall thread_pool_tests::Universe::* &)(void) const' 2> 'thread_pool_tests::Universe *' 2>threadpoolTest.cpp(78): error C2780: 'boost::unique_future<R> vst::async(F &&)' : expects 1 arguments - 2 provided 2> with 2> [ 2> R= 2> ]

On Fri, Apr 13, 2012 at 7:35 AM, John M. Dlugosz <mpbecey7gu@snkmail.com>wrote:
The plot thickens:
class Universe : std::tr1::enable_shared_from_**this<Universe> { const int answer; public: Universe (int a) : answer(a) {} std::string get_answer() const; void get_nothing() {} virtual void blahblah(); // !!! };
Universe u1(42); foo (&Universe::get_answer, &u1);
Regarding my previous post on the definitions of foo, if the class inherits from enable_shared_from this *and* contains a virtual function, then this call to foo doesn't work, giving funny template errors in boost::result_of.
It's really not so funny :) &Universe::get_answer is not an object supporting function-call syntax, so using boost::result_of to query the result of function application is, strictly speaking, meaningless. Boost.Bind happens to have special support for pointers-to-member-functions, but not all Boost libraries do, since it's a relatively simple matter to wrap the pointer in boost::mem_fun (note: I've actually forgotten the precise name). Regarding your initial message, on how to generically get the result type of a function object *or* a pointer-to-member-function, you'd need to create your own metafunction which dispatches to boost::result_of or Boost.FunctionTypes metafunctions depending on whether the argument is a pointer-to-member or not. You could argue that the language should allow function-call syntax on pointers-to-member-functions (and pointers-to-member-objects) as it is allowed for ponters-to-functions, and...I might sympathize with you. [snip errors] HTH, - Jeff

On Fri, Apr 13, 2012 at 9:15 AM, Jeffrey Lee Hellrung, Jr. < jeffrey.hellrung@gmail.com> wrote:
On Fri, Apr 13, 2012 at 7:35 AM, John M. Dlugosz <mpbecey7gu@snkmail.com>wrote:
The plot thickens:
class Universe : std::tr1::enable_shared_from_**this<Universe> { const int answer; public: Universe (int a) : answer(a) {} std::string get_answer() const; void get_nothing() {} virtual void blahblah(); // !!! };
Universe u1(42); foo (&Universe::get_answer, &u1);
Regarding my previous post on the definitions of foo, if the class inherits from enable_shared_from this *and* contains a virtual function, then this call to foo doesn't work, giving funny template errors in boost::result_of.
It's really not so funny :)
&Universe::get_answer is not an object supporting function-call syntax, so using boost::result_of to query the result of function application is, strictly speaking, meaningless. Boost.Bind happens to have special support for pointers-to-member-functions, but not all Boost libraries do, since it's a relatively simple matter to wrap the pointer in boost::mem_fun (note: I've actually forgotten the precise name).
Regarding your initial message, on how to generically get the result type of a function object *or* a pointer-to-member-function, you'd need to create your own metafunction which dispatches to boost::result_of or Boost.FunctionTypes metafunctions depending on whether the argument is a pointer-to-member or not.
You could argue that the language should allow function-call syntax on pointers-to-member-functions (and pointers-to-member-objects) as it is allowed for ponters-to-functions, and...I might sympathize with you.
[snip errors]
HTH,
- Jeff
Okay, disregard most of this, I checked the Boost.ResultOf implementation in 1.49.0, it does support pointers-to-members. Sorry, my bad! - Jeff
participants (2)
-
Jeffrey Lee Hellrung, Jr.
-
John M. Dlugosz