diff --git a/rclcpp/include/rclcpp/function_traits.hpp b/rclcpp/include/rclcpp/function_traits.hpp index d0b96be..7c64787 100644 --- a/rclcpp/include/rclcpp/function_traits.hpp +++ b/rclcpp/include/rclcpp/function_traits.hpp @@ -25,6 +25,7 @@ namespace rclcpp * but unfortunately std::function's constructor on VS2015 is too greedy, * so we need a mechanism for checking the arity and the type of each argument * in a callback function. + * See http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx */ @@ -58,6 +59,10 @@ struct function_traits : public function_traits {}; +/* NOTE(esteve): + * VS2015 does not support expression SFINAE, so we're using this template to evaluate + * the arity of a function. + */ template struct arity_comparator { diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 58bd8e7..b90631f 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -247,6 +247,16 @@ private: bool ignore_local_publications, typename message_memory_strategy::MessageMemoryStrategy::SharedPtr msg_mem_strat); +/* NOTE(esteve): + * The following template machinery works around VS2015's lack of support for expression SFINAE: + * - We first declare the arity we want to match, i.e. 2 or 3. + * - Then we use the arity_comparator template to SFINAE on the arity of the passed functor. + * - Lastly, we SFINAE on the types of the arguments of the functor. + * These steps happen in different parts of the function signature because we want to stagger + * instantation of the templates because VS2015 can't conditionally enable templates that depend + * on another template. + * See test_function_traits.cpp for streamlined examples of how to use this pattern. + */ template< typename ServiceT, typename FunctorT,