ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

How to use a Service Request as generic

asked 2021-12-31 10:42:46 -0500

xander-m2k gravatar image

I am trying to make a function which accepts a Service Request of any type, so something like this:
template<typename T, typename ServiceT>
bool sendRequest(std::shared_ptr<rclcpp::Client<T>> client, std::shared_ptr<ServiceT::Request> request);

The first parameter works fine, but the second parameter does not work, and I'm not sure how to do it correctly. How do I use the generic for a Service Request?

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
2

answered 2021-12-31 17:39:07 -0500

rnvandemark gravatar image

You're close! First, the template typenames T and ServiceT are the same types, so you only need to declare one, let's use ServiceT.

You did not specify why "the second parameter does not work", so it's impossible to know for sure what your issue is... The following could work:

template <typename ServiceT>
bool sendRequest(std::shared_ptr<rclcpp::Client<ServiceT>> client, std::shared_ptr<typename ServiceT::Request> request)
{
    // let 'node' be a std::shared_ptr<NodeType> declared elsewhere...
    auto result = client->async_send_request(request);
    return rclcpp::FutureReturnCode::SUCCESS == rclcpp::spin_until_future_complete(node, result);
}

The difference for the second argument is the typename keyword. Since this is a templated function, the compiler needs to know that for any ServiceT, that ServiceT::Request will be a type name. Without the typename keyword, the compiler doesn't have enough information to know your intention, e.g. ServiceT::Request could be a static data member.

In the future, you should at least include why "the second parameter does not work".

edit flag offensive delete link more

Comments

I'm sorry for describing a vague description of it not working. I knew the syntax was not correct, hence I simply said "it does not work", but actually it should be "incorrect syntax".

Anyway, I think this does work indeed. My goal was to make the function more intuitive for the user, so the functions second parameter would only be used with a request, because async_send_request() uses that as parameter. Apart from that, my first idea was to leave it just as std::shared_ptr<ServiceT> request, because I did not know how to do that.

I'm actually wondering how this works. For the first parameter it seems simple, because ServiceT will just be any type of the class rclcpp::Client. But, for the second argument, since ServiceT is not an actual type, how does the compiler know that the ServiceT type has a Request type, and how would that ...(more)

xander-m2k gravatar image xander-m2k  ( 2022-01-03 01:12:20 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2021-12-31 10:42:46 -0500

Seen: 73 times

Last updated: Dec 31 '21