zoukankan      html  css  js  c++  java
  • C++函数类型以及函数表实验

    C++的函数也有类型。比如:

    void func(int a);
    

    上面的函数的类型是: void(int)

    它可以作为模板类型参数,如同普通的类型一样:

    template<typename T> Foo;
    
    Foo<void(int)> foo;
    

    std::function模板就有类似的用法。

    我做了一个实验,设计一个函数表,但是是用模板的行式。来测试一下这个特殊的类型定义。

    代码如下:

    
    #include <array>
    #include <iostream>
    #include <map>
    
    template<typename FunctionType, size_t MAX_FUNC_TYPE>
    class FunctionMap
    {
    public:
    	bool RegisterFunction(size_t func_type, FunctionType* function)
    	{
    		if (nullptr == function) return false;
    		if (func_type >= MAX_FUNC_TYPE) return false;
    		if (m_function_map[func_type] != nullptr) return false;
    		m_function_map[func_type] = function;
    		return true;
    	}
    
    	template<typename... ParamType>
    	void CallFunction(size_t func_type, ParamType&&... param)
    	{
    		auto f = this->GetFunction(func_type);
    		if (nullptr != f)
    		{
    			f(std::forward<ParamType>(param)...);
    		}
    	}
    
    private:
    	FunctionType* GetFunction(size_t func_type)
    	{
    		if (func_type >= MAX_FUNC_TYPE) return nullptr;
    		return m_function_map[func_type];
    	}
    
    	std::array<FunctionType*, MAX_FUNC_TYPE> m_function_map{};
    };
    
    void Test(int a)
    {
    	std::cout << "Test " << a << std::endl;
    }
    
    int main()
    {
    	enum
    	{
    		FUNC_TYPE_1,
    		FUNC_TYPE_2,
    
    		FUNC_TYPE_MAX,
    	};
    
    	FunctionMap<void(int), FUNC_TYPE_MAX> fm;
    	fm.RegisterFunction(FUNC_TYPE_1, [](int i) { std::cout << "Func1 called " << i << std::endl; });
    	fm.RegisterFunction(FUNC_TYPE_2, [](int i) { std::cout << "Func2 called " << i << std::endl; });
    
    	fm.CallFunction(FUNC_TYPE_1, 42);
    	fm.CallFunction(FUNC_TYPE_2, 43);
    
    	std::cin.get();
    }
    

    函数类型如同数组类型一样,不能直接作为函数参数,需要转换成指针。

    CallFunction 函数这里使用了变长模板参数、万能引用+完美转发惯用法,从而实现了客户端调用接口。

  • 相关阅读:
    Windows自动更新所需要连接的网站列表
    DFX 9.303 for QQMusic 2010
    在VPC 2007 SP1中安装Ubuntu 10.04 desktop (完成)
    穷人把钱存入银行,实际上是补贴富人。
    清理Windows右下角图标
    阿里镜像pull 加速器
    k8s 安装flannel网络插件
    k8s pull.sh
    kubeadm1.10.00 安装k8s集群
    虚拟机vmware centos7 扩展磁盘空间
  • 原文地址:https://www.cnblogs.com/demon90s/p/15671806.html
Copyright © 2011-2022 走看看