远程过程调用-buttonrpc源码解析2-万能引用与完美转发

考虑远程调用的情况下,我们通过一定的技术手段,通知远程服务器调用某个函数来执行相应的功能,这就会涉及到万能引用与完美转发,其常见形式如下:

// <1>定义一个需要被调用的函数
void func(int a, double b, const char &c)
{
	std::cout << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
}
// <2>定义一个转发函数模板,完美转发args参数的值类型和值类别
template<typename F, typename... Args>
void forwardFunc(F&& func, Args&&... args)
{
	func(std::forward<Args>(args)...);
}

函数使用例子如下:

int main()
{
	int value = 1;
	forwardFunc(func, 1, 2.3, 'c');
	
	return 0;
}

但是在远程调用的情况下,我们需要将参数通过网络发送到服务器,就无法像上面用例那样直接调用函数并传递参数。但是我们可以通过一定的技术手段,明确的知道当前调用的是哪一个函数,以及这个函数的参数个数,便可以想办法将报文内容反序列化为std::tuple对象,并对其进行函数调用(反序列化的内容见第4节,这里假定已经可以成功得到std::tuple对象)

// 具体实现函数模板:用tuple做参数调用函数模板类
template<typename Function, typename Tuple, std::size_t... Index>
decltype(auto) invoke_impl(Function&& func, Tuple&& t, std::index_sequence<Index...>)
{
	return func(std::get<Index>(std::forward<Tuple>(t))...);
}
// 函数模板:作为一个接口,负责调用相关函数并传递参数
template<typename Function, typename Tuple>
decltype(auto) invoke(Function&& func, Tuple&& t)
{
	constexpr auto size = std::tuple_size<typename std::decay<Tuple>::type>::value;
	return invoke_impl(std::forward<Function>(func), std::forward<Tuple>(t), std::make_index_sequence<size>{});
}

温馨提示:关于万能引用和完美转发的用法

template<typename F, typename... Args>
void forwardFunc(F&& func, Args&&... args)
{
	func(std::forward<Args>(args)...);
}

以这里的F&& func举例来说,使用&&表示万能引用,而非右值引用,是为了解决F func丢失变量的cv属性(const和volatile)。
使用std::forward<Args>(args)...进行完美转发是为了解决值类别(左值或右值)问题,若不采用std::forward<Args>(args)...进行转发,即使Args&&... args作为forwardFunc(F&& func, Args&&... args)的参数被模板推导为右值引用类型,也会在forwardFunc(F&& func, Args&&... args)函数内变为左值(换句话说,就算args的类型被推导为右值引用类型,但args本身为左值,因为args仍可以在forwardFunc(F&& func, Args&&... args)内被重新赋值),而完美转发可以将其恢复为原本的值类别(原本是左值,完美转发后还是左值;原本是右值,完美转发后还是右值)。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮生卍流年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值