最近研究了一下MammothServer,发现里面有一个叫Dispatcher的实现,很有意思。正好自己最近在学习boost::mpl等东东,因此花了几天学习,并把自己的学习心得总结了一下。相信对大多数C++程序员会有帮助。
前言
在编写通讯框架时,经常要处理众多的协议。而处理完协议后,再调用相应的处理函数时,
在C++中,我们一般要使用统一接口。比如Windows消息中的MSG结构等等。
这种统一的处理结构最大的缺点是缺乏有效地类型检测,容易出错。因为,编译器无法对每一个特定消息进行数据合法性检查。
不过利用模板技术,完全可以实现RPC参数的解析以及与C++函数的自动匹配,支持不定长参数。
伪代码
class Dispatcher {
map<string, func> invokers_;
void register_function( const std::string& name, func);
void invoke( void* packet ) {
sequence params = deserialize( packet );
invokers_[ params["name"] ]( params );
}
}
void hello(const std::string& msg ) {
}
void hello2(const std::string& msg , const std::string& from) {
}
Dispatcher.register_function("hello", hello );
Dispatcher.register_function("hello2", hello2 );
准备知识
C++ template
boost::bind
boost::function 仿函数
boost::fusion 处理不同类型参数的sequence
boost::mpl 处理函数参数表的推导
part1 - basic framework
由于用户提供的函数带有不确定个数的参数,因此,在dispatcher内部,需要首先将用户提供的Function转换成为统一参数的仿函数,定义如下:
引用
出于讲解的需要,暂时不支持返回值,且与应用相关的参数被简化为一个void*
typedef boost::function<void(void*)> invoker_function_type;
相应的容器为
typedef std::map<std::string, invoker_function_type> dictionary_type;
注册函数考虑面向对象,因此包含函数Function和类实例Base.
class Dispatcher {
// 实际的invoke函数形式
typedef boost::function<void(void*)> invoker_function_type;
// name -> invoker 表
typedef std::map<std::string, invoker_function_type> dictionary_type;
dictionary_type m_invokers;
public:
template<typename Function, typename Base>
void register_function(std::string const & name, Function f, Base& base) {
m_invokers[name] = ...; //TODO
}
};
part2 - invoker
invoker是整个实现的核心。其中最重要的是对用户调用函数参数的自适应。
// predefinition
template<typename Function
,typename From = typename mpl::advance_c<typename mpl::begin< ft::parameter_types<Function> >::type, 1>::type
,typename To = typename mpl::end< ft::parameter_types<Function> >::type
>
struct Invoker;
// invoker,提取参数,放入sequence,继续调用
template<typename Function
,typename From
,typename To
>
struct Invoker
{
static void apply(Function func) {
typedef typename mpl::deref<From>::type arg_type; // 当前参数类型
typedef typename mpl::next<From>::type next_iter_type; // 下一个参数
typedef Invoker<Function, next_iter_type, To> NextInvoker;
NextInvoker::apply(func);
}
};
// 特化的invoker,结尾
template<typename Function
,typename To
>
struct Invoker<Function,To,To>
{
static void apply(Function func) {
std::cout << "finish";
}
};
template<typename Function>
void trigger(Function func) {
Invoker<Function>::apply( func );
}
不准确,但是直观的的描述可以理解为:
如果 函数为 func( int, char,void*),则实际生成的模板类分别是
Invoker< Function, int , void >;
Invoker< Function, char, void >;
Invoker< Function, void*, void >;
Invoker< Function, void, void >; //* 这个会匹配到特化的Invoker,从而结束递归
加入收集参数的模板参数
// invoker,提取参数,放入sequence,继续调用
template<typename Function
,typename From
,typename To
>
struct Invoker
{
template< typename Args >
static void apply(Function func, Args args) {
typedef typename mpl::deref<From>::type arg_type; // 当前参数类型
typedef typename mpl::next<From>::type next_iter_type; // 下一个参数
typedef Invoker<Function, next_iter_type, To> NextInvoker;
NextInvoker::apply(func, fusion::push_back(args,std::string("hello")));
}
};
// 特化的invoker,结尾
template<typename Function
,typename To
>
struct Invoker<Function,To,To>
{
template< typename Args >
static void apply(Function func,Args args) {
std::cout << args;
fusion::invoke(func, fusion::push_front(args, input)); // 完成对用户函数的调用
}
};
template<typename Function>
void trigger(Function func) {
Invoker<Function>::apply( func , fusion::nil() );
}
进一步实现对参数的提取,就可以实现一个完整的RPC的机制。
分享到:
相关推荐
在这个项目中,我们将探讨如何使用OpenCV的C++ API进行模板匹配。 模板匹配的基本思想是计算目标图像的每一个子区域与模板图像之间的相似度。OpenCV使用不同的方法来衡量这种相似度,如SIFT、SURF或简单的像素级...
在实际应用中,如人脸识别、物体检测、图像检索等场景,模板匹配都有广泛的应用。本文将深入探讨金字塔模板匹配算法及其在C++和OpenCV库中的实现。 ### 1. 模板匹配基础 模板匹配的基本思想是计算模板图像和待匹配...
在传统的模板匹配中,我们假设模板与目标图像区域是完全一致的,但在实际应用中,物体可能会由于角度变化而产生旋转。带旋转的模板匹配就是为了解决这一问题,它允许我们在未知旋转角度的情况下查找模板。 **旋转的...
C++模板特化匹配规则是指在C++编程语言中,模板的特化过程中,编译器如何选择最合适的模板实例化的规则。这个规则是由C++标准所定义的,目的是为了确保编译器能够正确地选择模板实例化,以便生成正确的机器代码。 ...
C++模板是C++语言中的一个强大特性,它允许程序员创建泛型代码,即能够处理多种数据类型的代码。模板在C++中分为两种主要类型:函数模板和类模板。函数模板用于定义可以接受不同类型参数的函数,而类模板用于创建...
模板匹配在许多领域都有应用,如人脸识别、车牌识别、图像检索等。然而,它也有一些局限性,比如对光照变化、角度变化和缩放不敏感,可能需要结合其他方法如尺度空间分析、特征提取等来提高鲁棒性。 在提供的压缩包...
程序首先会在模板图像上提取SURF特征,然后在待检测图像上同样提取特征。接下来,通过某种距离度量(如欧氏距离或余弦相似度)来比较两个图像的特征向量,找出最佳匹配对。最后,根据匹配的结果,可以确定模板图像在...
7. **SFINAE原则**:Substitution Failure Is Not An Error,意味着在模板实例化过程中,如果替换模板参数导致语法错误,该模板将被从候选列表中移除,而不是引发编译错误。 8. **模板别名**:C++11引入的`using`...
在字符识别中,我们首先需要一个已知字符的模板库,然后在待识别的字符图像中搜索最匹配的模板,以此判断字符类别。 二、C++编程环境 该项目要求在Windows 7操作系统下,使用Visual Studio 2010进行开发。Visual ...
8. **模板与异常处理**:如何在模板代码中适当地处理异常,以及异常处理对模板实例化的影响。 9. **模板与命名空间**:模板在命名空间中的行为,以及如何避免命名冲突和作用域问题。 10. **最佳实践与陷阱**:提供...
在基于边界的模板匹配中,我们首先需要一个模板图像,这个模板包含了我们要在大图像中寻找的特征。然后,我们将模板逐像素地滑过目标图像的每一个位置,计算模板与当前位置周围像素的相似度。传统的模板匹配通常使用...
C++中有关模板的试题题型练习题是C++模板类型题型的综合应用,涵盖了函数模板、类模板的设计方法和实现。下面对标题、描述、标签和部分内容进行详细的解释和分析。 一、函数模板设计 函数模板是C++模板技术的核心...
在计算机视觉领域,模板匹配是一种常见的图像处理技术,用于在大图像中寻找与给定模板相似的小区域。这个过程在目标检测、图像识别、视频分析等应用场景中非常有用。在本文中,我们将深入探讨如何使用QT作为图形用户...
1. 类型推导:在模板中,类型通常不是直接指定的,而是由模板参数决定。编译器会根据传入的实参自动推导出模板实例化的具体类型。 2. 模板特化:当通用模板不能满足特定类型的需求时,可以为特定类型定义模板特化,...
《C++模板元编程技术与应用》是一本深入探讨C++模板元编程的书籍,旨在让更多的C++程序员了解并掌握这一技术,从而在编程过程中提高效率和代码质量。模板元编程是C++中一种强大的静态编译时编程技术,它允许程序员在...
c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件模板 c++文件...
C++模板元编程是一种在编译时执行计算和创建代码的技术,它利用了C++模板系统的能力,将编程任务从运行时转移到了编译时。模板元编程允许开发者编写更高效、更灵活的代码,特别是在处理类型系统和泛型算法时。在本...
C++模板是C++编程语言中的一种重要机制,它允许开发者编写通用的函数和类,以适应不同的数据类型。模板的出现解决了函数重载的问题,使得代码更加简洁和灵活。本文将详细讲解C++模板的概念、声明、使用方法和优点。 ...