Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot create subscription to member function with extra argument using std::bind #766

Closed
sloretz opened this issue Jun 20, 2019 · 3 comments
Labels
backlog bug Something isn't working help wanted Extra attention is needed

Comments

@sloretz
Copy link
Contributor

sloretz commented Jun 20, 2019

Bug report

Required Info:

  • Operating System:
    • Bionic
  • Installation type:
    • Binaries
  • Version or commit hash:
    • 0.7.6-1bionic.20190612.221051
  • DDS implementation:
    • Fast-RTPS
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

Build this node, uncommenting each attempt to create the callback one at a time
#include <rclcpp/rclcpp.hpp>

#include <std_msgs/msg/string.hpp>

#include <functional>

class BindBug : public rclcpp::Node
{
public:
  explicit BindBug(const rclcpp::NodeOptions & options)
  : rclcpp::Node("bind_bug", options)
  {
    // First callback
    ///*
    auto callback = std::bind(
      &BindBug::on_msg,
      this,
      1,
      std::placeholders::_1);
    //*/

    // Second callback
    /*
    std::function<void(StringMsg::ConstSharedPtr)> callback = std::bind(
      &BindBug::on_msg,
      this,
      2,
      std::placeholders::_1);
    */

    // third callback
    /*
    auto callback =
      [this](StringMsg::ConstSharedPtr msg) {
        on_msg(3, msg);
      };
    */

    // Fourth callback
    /*
    auto callback = std::bind(
      &BindBug::reversed_on_msg,
      this,
      std::placeholders::_1,
      4);
    */

    // Fifth callback
    /*
    std::function<void(StringMsg::ConstSharedPtr)> callback = std::bind(
      &BindBug::reversed_on_msg,
      this,
      std::placeholders::_1,
      5);
    */
    
    sub_ = rclcpp::create_subscription<StringMsg>(
      this,
      "chatter",
      rclcpp::QoS(rclcpp::KeepLast(1)),
      callback);
  }

  virtual ~BindBug() = default;

private:
  using StringMsg = std_msgs::msg::String;

  void
  on_msg(size_t not_the_message, StringMsg::ConstSharedPtr msg)
  {
    RCLCPP_INFO(get_logger(), "Callback with [%zu] message '%s'", not_the_message, msg->data.c_str());
  }

  void
  reversed_on_msg(StringMsg::ConstSharedPtr msg, size_t not_the_message)
  {
    RCLCPP_INFO(get_logger(), "Callback with [%zu] message '%s'", not_the_message, msg->data.c_str());
  }

  rclcpp::Subscription<StringMsg>::SharedPtr sub_;
};


int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);

  rclcpp::NodeOptions opts;
  auto node = std::make_shared<BindBug>(opts);
  rclcpp::spin(node);

  rclcpp::shutdown();
  return 0;
}

Start the node and publish a string message

ros2 topic pub --once /chatter std_msgs/msg/String "{data: 'Hello world'}"

Expected behavior

All attempts at creating a subscription with a callback would work.

Actual behavior

First callback does not compile

Long compile output
/home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp: In constructor 'BindBug::BindBug(const rclcpp::NodeOptions&)':
/home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:61:15: error: no match for 'operator=' (operand types are 'rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >::SharedPtr {aka std::shared_ptr<rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > > >}' and 'std::shared_ptr<rclcpp::Subscription<long unsigned int, std::allocator<void> > >')
       callback);
               ^
In file included from /usr/include/c++/7/memory:81:0,
                 from /opt/ros/dashing/include/rclcpp/rclcpp.hpp:142,
                 from /home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:1:
/usr/include/c++/7/bits/shared_ptr.h:296:19: note: candidate: std::shared_ptr<_Tp>& std::shared_ptr<_Tp>::operator=(const std::shared_ptr<_Tp>&) [with _Tp = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >]
       shared_ptr& operator=(const shared_ptr&) noexcept = default;
                   ^~~~~~~~
/usr/include/c++/7/bits/shared_ptr.h:296:19: note:   no known conversion for argument 1 from 'std::shared_ptr<rclcpp::Subscription<long unsigned int, std::allocator<void> > >' to 'const std::shared_ptr<rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > > >&'
/usr/include/c++/7/bits/shared_ptr.h:300:2: note: candidate: template<class _Yp> std::shared_ptr<_Tp>::_Assignable<const std::shared_ptr<_Yp>&> std::shared_ptr<_Tp>::operator=(const std::shared_ptr<_Yp>&) [with _Yp = _Yp; _Tp = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >]
  operator=(const shared_ptr<_Yp>& __r) noexcept
  ^~~~~~~~
/usr/include/c++/7/bits/shared_ptr.h:300:2: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/shared_ptr.h:309:2: note: candidate: template<class _Yp> std::shared_ptr<_Tp>::_Assignable<std::auto_ptr<_Up> > std::shared_ptr<_Tp>::operator=(std::auto_ptr<_Up>&&) [with _Yp = _Yp; _Tp = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >]
  operator=(auto_ptr<_Yp>&& __r)
  ^~~~~~~~
/usr/include/c++/7/bits/shared_ptr.h:309:2: note:   template argument deduction/substitution failed:
/home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:61:15: note:   'std::shared_ptr<rclcpp::Subscription<long unsigned int, std::allocator<void> > >' is not derived from 'std::auto_ptr<_Up>'
       callback);
               ^
In file included from /usr/include/c++/7/memory:81:0,
                 from /opt/ros/dashing/include/rclcpp/rclcpp.hpp:142,
                 from /home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:1:
/usr/include/c++/7/bits/shared_ptr.h:317:7: note: candidate: std::shared_ptr<_Tp>& std::shared_ptr<_Tp>::operator=(std::shared_ptr<_Tp>&&) [with _Tp = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >]
       operator=(shared_ptr&& __r) noexcept
       ^~~~~~~~
/usr/include/c++/7/bits/shared_ptr.h:317:7: note:   no known conversion for argument 1 from 'std::shared_ptr<rclcpp::Subscription<long unsigned int, std::allocator<void> > >' to 'std::shared_ptr<rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > > >&&'
/usr/include/c++/7/bits/shared_ptr.h:325:2: note: candidate: template<class _Yp> std::shared_ptr<_Tp>::_Assignable<std::shared_ptr<_Yp> > std::shared_ptr<_Tp>::operator=(std::shared_ptr<_Yp>&&) [with _Yp = _Yp; _Tp = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >]
  operator=(shared_ptr<_Yp>&& __r) noexcept
  ^~~~~~~~
/usr/include/c++/7/bits/shared_ptr.h:325:2: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/shared_ptr.h:333:2: note: candidate: template<class _Yp, class _Del> std::shared_ptr<_Tp>::_Assignable<std::unique_ptr<_Up, _Ep> > std::shared_ptr<_Tp>::operator=(std::unique_ptr<_Up, _Ep>&&) [with _Yp = _Yp; _Del = _Del; _Tp = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >]
  operator=(unique_ptr<_Yp, _Del>&& __r)
  ^~~~~~~~
/usr/include/c++/7/bits/shared_ptr.h:333:2: note:   template argument deduction/substitution failed:
/home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:61:15: note:   'std::shared_ptr<rclcpp::Subscription<long unsigned int, std::allocator<void> > >' is not derived from 'std::unique_ptr<_Tp, _Dp>'
       callback);
               ^
In file included from /opt/ros/dashing/include/rclcpp/node_interfaces/node_topics_interface.hpp:29:0,
                 from /opt/ros/dashing/include/rclcpp/node.hpp:53,
                 from /opt/ros/dashing/include/rclcpp/executors/single_threaded_executor.hpp:28,
                 from /opt/ros/dashing/include/rclcpp/executors.hpp:22,
                 from /opt/ros/dashing/include/rclcpp/rclcpp.hpp:144,
                 from /home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:1:
/opt/ros/dashing/include/rclcpp/subscription_factory.hpp: In instantiation of 'rclcpp::SubscriptionFactory rclcpp::create_subscription_factory(CallbackT&&, const rclcpp::SubscriptionEventCallbacks&, typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr, std::shared_ptr<PublisherT>) [with MessageT = std_msgs::msg::String_<std::allocator<void> >; CallbackT = std::_Bind<void (BindBug::*(BindBug*, int, std::_Placeholder<1>))(long unsigned int, std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >)>&; Alloc = std::allocator<void>; CallbackMessageT = long unsigned int; SubscriptionT = rclcpp::Subscription<long unsigned int, std::allocator<void> >; typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr = std::shared_ptr<rclcpp::message_memory_strategy::MessageMemoryStrategy<long unsigned int, std::allocator<void> > >]':
/opt/ros/dashing/include/rclcpp/create_subscription.hpp:115:71:   required from 'std::shared_ptr<SubscriptionT> rclcpp::create_subscription(NodeT&&, const string&, const rclcpp::QoS&, CallbackT&&, const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT>&, typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr) [with MessageT = std_msgs::msg::String_<std::allocator<void> >; CallbackT = std::_Bind<void (BindBug::*(BindBug*, int, std::_Placeholder<1>))(long unsigned int, std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >)>&; AllocatorT = std::allocator<void>; CallbackMessageT = long unsigned int; SubscriptionT = rclcpp::Subscription<long unsigned int, std::allocator<void> >; NodeT = BindBug*; std::__cxx11::string = std::__cxx11::basic_string<char>; typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr = std::shared_ptr<rclcpp::message_memory_strategy::MessageMemoryStrategy<long unsigned int, std::allocator<void> > >]'
/home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:61:15:   required from here
/opt/ros/dashing/include/rclcpp/subscription_factory.hpp:88:3: error: no matching function for call to 'rclcpp::AnySubscriptionCallback<long unsigned int, std::allocator<void> >::set(std::_Bind<void (BindBug::*(BindBug*, int, std::_Placeholder<1>))(long unsigned int, std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >)>&)'
   any_subscription_callback.set(std::forward<CallbackT>(callback));
   ^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/ros/dashing/include/rclcpp/subscription_base.hpp:28:0,
                 from /opt/ros/dashing/include/rclcpp/intra_process_manager_impl.hpp:38,
                 from /opt/ros/dashing/include/rclcpp/intra_process_manager.hpp:32,
                 from /opt/ros/dashing/include/rclcpp/publisher.hpp:35,
                 from /opt/ros/dashing/include/rclcpp/callback_group.hpp:24,
                 from /opt/ros/dashing/include/rclcpp/any_executable.hpp:20,
                 from /opt/ros/dashing/include/rclcpp/memory_strategy.hpp:24,
                 from /opt/ros/dashing/include/rclcpp/memory_strategies.hpp:18,
                 from /opt/ros/dashing/include/rclcpp/executor.hpp:32,
                 from /opt/ros/dashing/include/rclcpp/executors/multi_threaded_executor.hpp:24,
                 from /opt/ros/dashing/include/rclcpp/executors.hpp:21,
                 from /opt/ros/dashing/include/rclcpp/rclcpp.hpp:144,
                 from /home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:1:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:80:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<long unsigned int>)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<_Tp>)> >::value>::type* <anonymous> = <enumerator>; MessageT = long unsigned int; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:80:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:78:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:78:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:94:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<long unsigned int>, const rmw_message_info_t&)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<_Tp>, const rmw_message_info_t&)> >::value>::type* <anonymous> = <enumerator>; MessageT = long unsigned int; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:94:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:92:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:92:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:108:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<const long unsigned int>)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<const _Tp>)> >::value>::type* <anonymous> = <enumerator>; MessageT = long unsigned int; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:108:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:106:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:106:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:122:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<const long unsigned int>, const rmw_message_info_t&)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<const _Tp>, const rmw_message_info_t&)> >::value>::type* <anonymous> = <enumerator>; MessageT = long unsigned int; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:122:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:120:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:120:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:136:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::unique_ptr<long unsigned int, std::default_delete<long unsigned int> >)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::unique_ptr<T, typename std::conditional<std::is_same<typename std::allocator_traits<typename std::allocator_traits<_Alloc>::rebind_traits<T>::allocator_type>::rebind_alloc<T>, typename std::allocator<void>::rebind<_Tp1>::other>::value, std::default_delete<_Tp>, rclcpp::allocator::AllocatorDeleter<typename std::allocator_traits<_Alloc>::rebind_traits<T>::allocator_type> >::type>)> >::value>::type* <anonymous> = <enumerator>; MessageT = long unsigned int; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:136:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:134:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:134:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:150:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::unique_ptr<long unsigned int, std::default_delete<long unsigned int> >, const rmw_message_info_t&)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::unique_ptr<T, typename std::conditional<std::is_same<typename std::allocator_traits<typename std::allocator_traits<_Alloc>::rebind_traits<T>::allocator_type>::rebind_alloc<T>, typename std::allocator<void>::rebind<_Tp1>::other>::value, std::default_delete<_Tp>, rclcpp::allocator::AllocatorDeleter<typename std::allocator_traits<_Alloc>::rebind_traits<T>::allocator_type> >::type>, const rmw_message_info_t&)> >::value>::type* <anonymous> = <enumerator>; MessageT = long unsigned int; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:150:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:148:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:148:17: note: invalid template non-type parameter
In file included from /usr/include/c++/7/future:48:0,
                 from /opt/ros/dashing/include/rclcpp/executors.hpp:18,
                 from /opt/ros/dashing/include/rclcpp/rclcpp.hpp:144,
                 from /home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:1:
/usr/include/c++/7/bits/std_function.h: At global scope:
/usr/include/c++/7/bits/std_function.h:541:2: error: 'std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<typename std::decay<_U1>::type>, std::function<_Res(_ArgTypes ...)>&> std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = rclcpp::create_subscription_factory(CallbackT&&, const rclcpp::SubscriptionEventCallbacks&, typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr, std::shared_ptr<PublisherT>) [with MessageT = std_msgs::msg::String_<std::allocator<void> >; CallbackT = std::_Bind<void (BindBug::*(BindBug*, int, std::_Placeholder<1>))(long unsigned int, std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >)>&; Alloc = std::allocator<void>; CallbackMessageT = long unsigned int; SubscriptionT = rclcpp::Subscription<long unsigned int, std::allocator<void> >; typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr = std::shared_ptr<rclcpp::message_memory_strategy::MessageMemoryStrategy<long unsigned int, std::allocator<void> > >]::<lambda(rclcpp::node_interfaces::NodeBaseInterface*, const string&, const rcl_subscription_options_t&)>; _Res = std::shared_ptr<rclcpp::SubscriptionBase>; _ArgTypes = {rclcpp::node_interfaces::NodeBaseInterface*, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const rcl_subscription_options_t&}; std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<typename std::decay<_U1>::type>, std::function<_Res(_ArgTypes ...)>&> = std::function<std::shared_ptr<rclcpp::SubscriptionBase>(rclcpp::node_interfaces::NodeBaseInterface*, const std::__cxx11::basic_string<char>&, const rcl_subscription_options_t&)>&]', declared using local type 'rclcpp::create_subscription_factory(CallbackT&&, const rclcpp::SubscriptionEventCallbacks&, typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr, std::shared_ptr<PublisherT>) [with MessageT = std_msgs::msg::String_<std::allocator<void> >; CallbackT = std::_Bind<void (BindBug::*(BindBug*, int, std::_Placeholder<1>))(long unsigned int, std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >)>&; Alloc = std::allocator<void>; CallbackMessageT = long unsigned int; SubscriptionT = rclcpp::Subscription<long unsigned int, std::allocator<void> >; typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr = std::shared_ptr<rclcpp::message_memory_strategy::MessageMemoryStrategy<long unsigned int, std::allocator<void> > >]::<lambda(rclcpp::node_interfaces::NodeBaseInterface*, const string&, const rcl_subscription_options_t&)>', is used but never defined [-fpermissive]
  operator=(_Functor&& __f)
  ^~~~~~~~
make[2]: *** [CMakeFiles/bind_bug.dir/src/bind_bug.cpp.o] Error 1
make[1]: *** [CMakeFiles/bind_bug.dir/all] Error 2
make: *** [all] Error 2

Second callback (bind assigned to std::function) works fine

[INFO] [bind_bug]: Callback with [2] message 'Hello world'

Third callback (wrapping call with lambda) works fine

[INFO] [bind_bug]: Callback with [3] message 'Hello world'

Fourth callback (reversed argument order to bind) fails to compile

Long compile output
In file included from /opt/ros/dashing/include/rclcpp/node_interfaces/node_topics_interface.hpp:29:0,
                 from /opt/ros/dashing/include/rclcpp/node.hpp:53,
                 from /opt/ros/dashing/include/rclcpp/executors/single_threaded_executor.hpp:28,
                 from /opt/ros/dashing/include/rclcpp/executors.hpp:22,
                 from /opt/ros/dashing/include/rclcpp/rclcpp.hpp:144,
                 from /home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:1:
/opt/ros/dashing/include/rclcpp/subscription_factory.hpp: In instantiation of 'rclcpp::SubscriptionFactory rclcpp::create_subscription_factory(CallbackT&&, const rclcpp::SubscriptionEventCallbacks&, typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr, std::shared_ptr<PublisherT>) [with MessageT = std_msgs::msg::String_<std::allocator<void> >; CallbackT = std::_Bind<void (BindBug::*(BindBug*, std::_Placeholder<1>, int))(std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >, long unsigned int)>&; Alloc = std::allocator<void>; CallbackMessageT = std_msgs::msg::String_<std::allocator<void> >; SubscriptionT = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >; typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr = std::shared_ptr<rclcpp::message_memory_strategy::MessageMemoryStrategy<std_msgs::msg::String_<std::allocator<void> >, std::allocator<void> > >]':
/opt/ros/dashing/include/rclcpp/create_subscription.hpp:115:71:   required from 'std::shared_ptr<SubscriptionT> rclcpp::create_subscription(NodeT&&, const string&, const rclcpp::QoS&, CallbackT&&, const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT>&, typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr) [with MessageT = std_msgs::msg::String_<std::allocator<void> >; CallbackT = std::_Bind<void (BindBug::*(BindBug*, std::_Placeholder<1>, int))(std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >, long unsigned int)>&; AllocatorT = std::allocator<void>; CallbackMessageT = std_msgs::msg::String_<std::allocator<void> >; SubscriptionT = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >; NodeT = BindBug*; std::__cxx11::string = std::__cxx11::basic_string<char>; typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr = std::shared_ptr<rclcpp::message_memory_strategy::MessageMemoryStrategy<std_msgs::msg::String_<std::allocator<void> >, std::allocator<void> > >]'
/home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:61:15:   required from here
/opt/ros/dashing/include/rclcpp/subscription_factory.hpp:88:3: error: no matching function for call to 'rclcpp::AnySubscriptionCallback<std_msgs::msg::String_<std::allocator<void> >, std::allocator<void> >::set(std::_Bind<void (BindBug::*(BindBug*, std::_Placeholder<1>, int))(std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >, long unsigned int)>&)'
   any_subscription_callback.set(std::forward<CallbackT>(callback));
   ^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/ros/dashing/include/rclcpp/subscription_base.hpp:28:0,
                 from /opt/ros/dashing/include/rclcpp/intra_process_manager_impl.hpp:38,
                 from /opt/ros/dashing/include/rclcpp/intra_process_manager.hpp:32,
                 from /opt/ros/dashing/include/rclcpp/publisher.hpp:35,
                 from /opt/ros/dashing/include/rclcpp/callback_group.hpp:24,
                 from /opt/ros/dashing/include/rclcpp/any_executable.hpp:20,
                 from /opt/ros/dashing/include/rclcpp/memory_strategy.hpp:24,
                 from /opt/ros/dashing/include/rclcpp/memory_strategies.hpp:18,
                 from /opt/ros/dashing/include/rclcpp/executor.hpp:32,
                 from /opt/ros/dashing/include/rclcpp/executors/multi_threaded_executor.hpp:24,
                 from /opt/ros/dashing/include/rclcpp/executors.hpp:21,
                 from /opt/ros/dashing/include/rclcpp/rclcpp.hpp:144,
                 from /home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:1:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:80:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<std_msgs::msg::String_<std::allocator<void> > >)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<_Tp>)> >::value>::type* <anonymous> = <enumerator>; MessageT = std_msgs::msg::String_<std::allocator<void> >; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:80:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:78:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:78:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:94:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<std_msgs::msg::String_<std::allocator<void> > >, const rmw_message_info_t&)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<_Tp>, const rmw_message_info_t&)> >::value>::type* <anonymous> = <enumerator>; MessageT = std_msgs::msg::String_<std::allocator<void> >; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:94:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:92:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:92:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:108:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<const _Tp>)> >::value>::type* <anonymous> = <enumerator>; MessageT = std_msgs::msg::String_<std::allocator<void> >; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:108:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:106:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:106:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:122:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >, const rmw_message_info_t&)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::shared_ptr<const _Tp>, const rmw_message_info_t&)> >::value>::type* <anonymous> = <enumerator>; MessageT = std_msgs::msg::String_<std::allocator<void> >; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:122:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:120:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:120:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:136:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::unique_ptr<std_msgs::msg::String_<std::allocator<void> >, std::default_delete<std_msgs::msg::String_<std::allocator<void> > > >)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::unique_ptr<T, typename std::conditional<std::is_same<typename std::allocator_traits<typename std::allocator_traits<_Alloc>::rebind_traits<T>::allocator_type>::rebind_alloc<T>, typename std::allocator<void>::rebind<_Tp1>::other>::value, std::default_delete<_Tp>, rclcpp::allocator::AllocatorDeleter<typename std::allocator_traits<_Alloc>::rebind_traits<T>::allocator_type> >::type>)> >::value>::type* <anonymous> = <enumerator>; MessageT = std_msgs::msg::String_<std::allocator<void> >; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:136:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:134:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:134:17: note: invalid template non-type parameter
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:150:8: note: candidate: template<class CallbackT, typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::unique_ptr<std_msgs::msg::String_<std::allocator<void> >, std::default_delete<std_msgs::msg::String_<std::allocator<void> > > >, const rmw_message_info_t&)> >::value, void>::type* <anonymous> > void rclcpp::AnySubscriptionCallback<MessageT, Alloc>::set(CallbackT) [with CallbackT = CallbackT; typename std::enable_if<rclcpp::function_traits::same_arguments<CallbackT, std::function<void(std::unique_ptr<T, typename std::conditional<std::is_same<typename std::allocator_traits<typename std::allocator_traits<_Alloc>::rebind_traits<T>::allocator_type>::rebind_alloc<T>, typename std::allocator<void>::rebind<_Tp1>::other>::value, std::default_delete<_Tp>, rclcpp::allocator::AllocatorDeleter<typename std::allocator_traits<_Alloc>::rebind_traits<T>::allocator_type> >::type>, const rmw_message_info_t&)> >::value>::type* <anonymous> = <enumerator>; MessageT = std_msgs::msg::String_<std::allocator<void> >; Alloc = std::allocator<void>]
   void set(CallbackT callback)
        ^~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:150:8: note:   template argument deduction/substitution failed:
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:148:17: error: no type named 'type' in 'struct std::enable_if<false, void>'
     >::type * = nullptr
                 ^~~~~~~
/opt/ros/dashing/include/rclcpp/any_subscription_callback.hpp:148:17: note: invalid template non-type parameter
In file included from /usr/include/c++/7/future:48:0,
                 from /opt/ros/dashing/include/rclcpp/executors.hpp:18,
                 from /opt/ros/dashing/include/rclcpp/rclcpp.hpp:144,
                 from /home/sloretz/workspaces/dashing/src/lifecycle_manager/src/bind_bug.cpp:1:
/usr/include/c++/7/bits/std_function.h:541:2: error: 'std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<typename std::decay<_U1>::type>, std::function<_Res(_ArgTypes ...)>&> std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = rclcpp::create_subscription_factory(CallbackT&&, const rclcpp::SubscriptionEventCallbacks&, typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr, std::shared_ptr<PublisherT>) [with MessageT = std_msgs::msg::String_<std::allocator<void> >; CallbackT = std::_Bind<void (BindBug::*(BindBug*, std::_Placeholder<1>, int))(std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >, long unsigned int)>&; Alloc = std::allocator<void>; CallbackMessageT = std_msgs::msg::String_<std::allocator<void> >; SubscriptionT = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >; typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr = std::shared_ptr<rclcpp::message_memory_strategy::MessageMemoryStrategy<std_msgs::msg::String_<std::allocator<void> >, std::allocator<void> > >]::<lambda(rclcpp::node_interfaces::NodeBaseInterface*, const string&, const rcl_subscription_options_t&)>; _Res = std::shared_ptr<rclcpp::SubscriptionBase>; _ArgTypes = {rclcpp::node_interfaces::NodeBaseInterface*, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const rcl_subscription_options_t&}; std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<typename std::decay<_U1>::type>, std::function<_Res(_ArgTypes ...)>&> = std::function<std::shared_ptr<rclcpp::SubscriptionBase>(rclcpp::node_interfaces::NodeBaseInterface*, const std::__cxx11::basic_string<char>&, const rcl_subscription_options_t&)>&]', declared using local type 'rclcpp::create_subscription_factory(CallbackT&&, const rclcpp::SubscriptionEventCallbacks&, typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr, std::shared_ptr<PublisherT>) [with MessageT = std_msgs::msg::String_<std::allocator<void> >; CallbackT = std::_Bind<void (BindBug::*(BindBug*, std::_Placeholder<1>, int))(std::shared_ptr<const std_msgs::msg::String_<std::allocator<void> > >, long unsigned int)>&; Alloc = std::allocator<void>; CallbackMessageT = std_msgs::msg::String_<std::allocator<void> >; SubscriptionT = rclcpp::Subscription<std_msgs::msg::String_<std::allocator<void> > >; typename rclcpp::message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, Alloc>::SharedPtr = std::shared_ptr<rclcpp::message_memory_strategy::MessageMemoryStrategy<std_msgs::msg::String_<std::allocator<void> >, std::allocator<void> > >]::<lambda(rclcpp::node_interfaces::NodeBaseInterface*, const string&, const rcl_subscription_options_t&)>', is used but never defined [-fpermissive]
  operator=(_Functor&& __f)
  ^~~~~~~~
make[2]: *** [CMakeFiles/bind_bug.dir/src/bind_bug.cpp.o] Error 1
make[1]: *** [CMakeFiles/bind_bug.dir/all] Error 2
make: *** [all] Error 2

Fifth callback (Reversed argument order with bind assigned to std::function) works fine

[INFO] [bind_bug]: Callback with [5] message 'Hello world'

Additional information

@sloretz sloretz added the bug Something isn't working label Jun 20, 2019
@wjwwood
Copy link
Member

wjwwood commented Jul 11, 2019

I think this is the issue that may be related:

#583

And the ROS answer referenced from that issue:

https://answers.ros.org/question/308386/ros2-add-arguments-to-callback/

@Karsten1987
Copy link
Contributor

Karsten1987 commented Sep 10, 2019

same thing as #273 ?

@dirk-thomas
Copy link
Member

To summarize: I think the failing cases are not supported since we can't ensure at compile time that the signature using std::bind is correct. Therefore I will go ahead and close this ticket.

Please feel free to continue commenting on it and it can be reopened if necessary.

sloretz added a commit to sloretz/perception_pcl that referenced this issue Nov 23, 2019
Signed-off-by: Shane Loretz <[email protected]>
mbuijs pushed a commit to mbuijs/stage_ros that referenced this issue May 18, 2020
mbuijs pushed a commit to mbuijs/stage_ros that referenced this issue May 26, 2020
mbuijs pushed a commit to mbuijs/stage_ros that referenced this issue May 26, 2020
mbuijs added a commit to mbuijs/stage_ros that referenced this issue Jun 9, 2020
mbuijs added a commit to mbuijs/stage_ros that referenced this issue Jun 9, 2020
mbuijs added a commit to mbuijs/stage_ros that referenced this issue Jun 9, 2020
nnmm pushed a commit to ApexAI/rclcpp that referenced this issue Jul 9, 2022
* Fault injection tests for rcl_yaml

Signed-off-by: Stephen Brawner <[email protected]>

* PR Feedback

Signed-off-by: Stephen Brawner <[email protected]>

* Pause fault injection

Signed-off-by: Stephen Brawner <[email protected]>

* variant_copy

Signed-off-by: Stephen Brawner <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

5 participants