[libsigc++2] C++11: deduce_result_type: Simplify with variadic template and std::conditional<>.



commit e1da5e0808c068ceb3c4f87d3fd84e338e38a1f5
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Aug 14 23:21:09 2015 +0200

    C++11: deduce_result_type: Simplify with variadic template and std::conditional<>.
    
    Bug #753612
    However, the build then fails like so:
    
    make[2]: Entering directory '/home/murrayc/checkout/gnome/libsigc++2/examples'
    g++ -DHAVE_CONFIG_H   -I.. -I..  -pedantic -Wall -Wextra -Wshadow -Wformat-security -Werror -Wall -g -O0 
-std=c++11 -MT hello_world.o -MD -MP -MF .deps/hello_world.Tpo -c -o hello_world.o hello_world.cc
    In file included from ../sigc++/adaptors/adaptor_trait.h:10:0,
                     from ../sigc++/functors/slot.h:7,
                     from ../sigc++/signal_base.h:27,
                     from ../sigc++/signal.h:8,
                     from ../sigc++/sigc++.h:86,
                     from hello_world.cc:10:
    ../sigc++/adaptors/deduce_result_type.h: In instantiation of ‘struct 
sigc::deduce_result_type<sigc::pointer_functor1<const std::basic_string<char>&, void>, const 
std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, void, void, void, void, void, void>’:
    ../sigc++/adaptors/deduce_result_type.h:60:80:   required by substitution of ‘template<class T_functor, 
class ... T_args> using deduce_result_t = typename sigc::deduce_result_type::type [with T_functor = 
sigc::pointer_functor1<const std::basic_string<char>&, void>; T_args = {const std::basic_string<char, 
std::char_traits<char>, std::allocator<char> >&, void, void, void, void, void, void}]’
    ../sigc++/adaptors/adaptor_trait.h:67:104:   required from ‘struct 
sigc::adaptor_functor<sigc::pointer_functor1<const std::basic_string<char>&, void> 
::deduce_result_type<const std::basic_string<char>&, void, void, void, void, void, void>’
    ../sigc++/adaptors/adaptor_trait.h:88:3:   required by substitution of ‘template<class T_arg1> typename 
sigc::adaptor_functor<T_functor>::deduce_result_type<T_arg1>::type 
sigc::adaptor_functor<T_functor>::operator()(T_arg1) const [with T_arg1 = const std::basic_string<char>&]’
    ../sigc++/functors/slot.h:137:20:   required from ‘static T_return sigc::internal::slot_call1<T_functor, 
T_return, T_arg1>::call_it(sigc::internal::slot_rep*, sigc::type_trait_take_t<T_arg3>) [with T_functor = 
sigc::pointer_functor1<const std::basic_string<char>&, void>; T_return = void; T_arg1 = const 
std::basic_string<char>&; sigc::type_trait_take_t<T_arg3> = const std::basic_string<char>&]’
    ../sigc++/functors/slot.h:144:37:   required from ‘static void* (* sigc::internal::slot_call1<T_functor, 
T_return, T_arg1>::address())(void*) [with T_functor = sigc::pointer_functor1<const std::basic_string<char>&, 
void>; T_return = void; T_arg1 = const std::basic_string<char>&; sigc::internal::hook = void* (*)(void*)]’
    ../sigc++/functors/slot.h:529:91:   required from ‘sigc::slot1<T_return, T_arg1>::slot1(const T_functor&) 
[with T_functor = sigc::pointer_functor1<const std::basic_string<char>&, void>; T_return = void; T_arg1 = 
const std::basic_string<char>&]’
    ../sigc++/functors/slot.h:1161:26:   required from ‘sigc::slot<T_return, T_arg1, sigc::nil, sigc::nil, 
sigc::nil, sigc::nil, sigc::nil, sigc::nil>::slot(const T_functor&) [with T_functor = 
sigc::pointer_functor1<const std::basic_string<char>&, void>; T_return = void; T_arg1 = const 
std::basic_string<char>&]’
    hello_world.cc:25:50:   required from here
    ../sigc++/adaptors/deduce_result_type.h:56:12: error: no class template named ‘deduce_result_type’ in 
‘class sigc::pointer_functor1<const std::basic_string<char>&, void>’
         >::type;
                ^
    In file included from ../sigc++/signal_base.h:27:0,
                     from ../sigc++/signal.h:8,
                     from ../sigc++/sigc++.h:86,
                     from hello_world.cc:10:
    ../sigc++/functors/slot.h: In instantiation of ‘static T_return sigc::internal::slot_call1<T_functor, 
T_return, T_arg1>::call_it(sigc::internal::slot_rep*, sigc::type_trait_take_t<T_arg3>) [with T_functor = 
sigc::pointer_functor1<const std::basic_string<char>&, void>; T_return = void; T_arg1 = const 
std::basic_string<char>&; sigc::type_trait_take_t<T_arg3> = const std::basic_string<char>&]’:
    ../sigc++/functors/slot.h:144:37:   required from ‘static void* (* sigc::internal::slot_call1<T_functor, 
T_return, T_arg1>::address())(void*) [with T_functor = sigc::pointer_functor1<const std::basic_string<char>&, 
void>; T_return = void; T_arg1 = const std::basic_string<char>&; sigc::internal::hook = void* (*)(void*)]’
    ../sigc++/functors/slot.h:529:91:   required from ‘sigc::slot1<T_return, T_arg1>::slot1(const T_functor&) 
[with T_functor = sigc::pointer_functor1<const std::basic_string<char>&, void>; T_return = void; T_arg1 = 
const std::basic_string<char>&]’
    ../sigc++/functors/slot.h:1161:26:   required from ‘sigc::slot<T_return, T_arg1, sigc::nil, sigc::nil, 
sigc::nil, sigc::nil, sigc::nil, sigc::nil>::slot(const T_functor&) [with T_functor = 
sigc::pointer_functor1<const std::basic_string<char>&, void>; T_return = void; T_arg1 = const 
std::basic_string<char>&]’
    hello_world.cc:25:50:   required from here
    ../sigc++/functors/slot.h:137:20: error: no matching function for call to 
‘sigc::adaptor_functor<sigc::pointer_functor1<const std::basic_string<char>&, void> >::operator()(const 
std::basic_string<char>&)’
                    (a_1);
                        ^
    ../sigc++/functors/slot.h:137:20: note: candidates are:
    In file included from ../sigc++/functors/slot.h:7:0,
                     from ../sigc++/signal_base.h:27,
                     from ../sigc++/signal.h:8,
                     from ../sigc++/sigc++.h:86,
                     from hello_world.cc:10:
    ../sigc++/adaptors/adaptor_trait.h:88:3: note: template<class T_arg1> typename 
sigc::adaptor_functor<T_functor>::deduce_result_type<T_arg1>::type 
sigc::adaptor_functor<T_functor>::operator()(T_arg1) const [with T_arg1 = T_arg1; T_functor = 
sigc::pointer_functor1<const std::basic_string<char>&, void>]
       operator()(T_arg1 _A_arg1) const
       ^
    ../sigc++/adaptors/adaptor_trait.h:88:3: note:   substitution of deduced template arguments resulted in 
errors seen above
    ../sigc++/adaptors/adaptor_trait.h:107:3: note: template<class T_arg1, class T_arg2> typename 
sigc::adaptor_functor<T_functor>::deduce_result_type<T_arg1, T_arg2>::type 
sigc::adaptor_functor<T_functor>::operator()(T_arg1, T_arg2) const [with T_arg1 = T_arg1; T_arg2 = T_arg2; 
T_functor = sigc::pointer_functor1<const std::basic_string<char>&, void>]
       operator()(T_arg1 _A_arg1, T_arg2 _A_arg2) const
       ^
    ../sigc++/adaptors/adaptor_trait.h:107:3: note:   template argument deduction/substitution failed:
    In file included from ../sigc++/signal_base.h:27:0,
                     from ../sigc++/signal.h:8,
                     from ../sigc++/sigc++.h:86,
                     from hello_world.cc:10:
    ../sigc++/functors/slot.h:137:20: note:   candidate expects 2 arguments, 1 provided
                    (a_1);
                        ^

 sigc++/adaptors/macros/deduce_result_type.h.m4 |   40 +++++------------------
 1 files changed, 9 insertions(+), 31 deletions(-)
---
diff --git a/sigc++/adaptors/macros/deduce_result_type.h.m4 b/sigc++/adaptors/macros/deduce_result_type.h.m4
index c31da7d..8e5557e 100644
--- a/sigc++/adaptors/macros/deduce_result_type.h.m4
+++ b/sigc++/adaptors/macros/deduce_result_type.h.m4
@@ -17,28 +17,6 @@ dnl
 divert(-1)
 include(template.macros.m4)
 
-define([DEDUCE_RESULT_TYPE_ADAPTOR],[dnl
-/** Deduce the return type of a functor.
- * This is the template specialization of the sigc::deduce_result_type template
- * for $1 arguments.
- */
-template <LIST(class T_functor, LOOP(class T_arg%1, $1))>
-struct deduce_result_type<LIST(T_functor, LOOP(T_arg%1,$1), LOOP(void,eval($2-$1)), true)>
-  { typedef typename T_functor::template deduce_result_type<LOOP(T_arg%1,$1)>::type type; };
-
-])
-dnl 01.11.2003: Completely removed support for typeof() since it is non-standard!
-dnl define([DEDUCE_RESULT_TYPE_TYPEOF],[dnl
-dnl template <LIST(class T_functor, LOOP(class T_arg%1, $1))>
-dnl struct deduce_result_type<LIST(T_functor, LOOP(T_arg%1,$1), LOOP(void,eval($2-$1)), false)>
-dnl {
-dnl   typedef typeof(type_trait<T_functor>::instance().
-dnl                    T_functor::operator()(LOOP([
-dnl                       type_trait<T_arg%1>::instance()], $1))) type;
-dnl };
-dnl 
-dnl ])
-
 divert(0)dnl
 /*
 */
@@ -84,20 +62,20 @@ struct adaptor_base : public functor_base {};
  *
  * @ingroup adaptors
  */
-template <class T_functor,
-          LOOP(class T_arg%1=void, CALL_SIZE),
-          bool I_derives_adaptor_base = std::is_base_of<adaptor_base,T_functor>::value>
+template<class T_functor, class... T_args>
 struct deduce_result_type
-  { typedef typename functor_trait<T_functor>::result_type type; };
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-FOR(0,CALL_SIZE,[[DEDUCE_RESULT_TYPE_ADAPTOR(%1,CALL_SIZE)]])dnl
+{
+  using type =
+    typename std::conditional<
+      std::is_base_of<adaptor_base, T_functor>::value,
+      typename T_functor::template deduce_result_type<T_args...>::type,
+      typename functor_trait<T_functor>::result_type
+    >::type;
+};
 
 template<typename T_functor, typename... T_args>
 using deduce_result_t = typename deduce_result_type<T_functor, T_args...>::type;
 
-#endif // DOXYGEN_SHOULD_SKIP_THIS
-
 dnl #ifdef SIGC_CXX_TYPEOF
 dnl FOR(0,CALL_SIZE,[[DEDUCE_RESULT_TYPE_TYPEOF(%1,CALL_SIZE)]])
 dnl #endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]