惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
宝玉的分享
宝玉的分享
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
P
Privacy International News Feed
T
Threatpost
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
NISL@THU
NISL@THU
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
雷峰网
雷峰网
Know Your Adversary
Know Your Adversary
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
Intezer
博客园 - Franky
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
The Hacker News
The Hacker News
K
Kaspersky official blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tailwind CSS Blog
Project Zero
Project Zero
T
Tor Project blog
B
Blog RSS Feed
Recorded Future
Recorded Future
Scott Helme
Scott Helme
美团技术团队
V
V2EX
V
Visual Studio Blog
L
Lohrmann on Cybersecurity
P
Proofpoint News Feed
D
DataBreaches.Net
The Register - Security
The Register - Security
M
MIT News - Artificial intelligence
L
LangChain Blog
Cisco Talos Blog
Cisco Talos Blog
博客园 - 三生石上(FineUI控件)
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园_首页
P
Privacy & Cybersecurity Law Blog

博客园 - shootingstars

硬件相关概念 C的可变参数 C++概念网摘 Mifare 串行读取协议 韦根协议 学习C的可变参数 关于汇编程序调用各种C函数的例子 如何移植Java的类中的super到C++代码中 编译原理学习 关于标准库中的ptr_fun/binary_function/bind1st/bind2nd 使用python编写每日构建工具 boost::regex学习(5) - shootingstars - 博客园 boost::regex学习(4) - shootingstars - 博客园 boost::regex学习(3) boost::regex学习(2) 《世界大战》《变形金刚》观后感 boost::regex学习(1) boost::algorithm学习 五种迭代器
我的Function
shootingstars · 2010-01-11 · via 博客园 - shootingstars

我们有些时候需要存储一些函数以备后用,最常用的就是C中的Callback。。。
但是到了C++年代,函数都放到了类中,想要Callback就有些复杂了。Boost::function封装了一个模版库,它可以接受静态函数,普通函数以及仿函数,为了了解它的原理,我自己试图写一个简单的类。。。

我们先看boost中function的使用
boost::function<int(int)> func; // 能接受int(int)型的函数或仿函数
在模版参数中我们看到int(int) ,这个可能一般用户感到陌生,其实它是一个函数类型,表示返回值是int,并且有一个参数是int的函数类型。
一直以来令我感到困惑的是:int(int)仅仅是一个类型,一般而言我们如果需要用模版接受这个参数的话,可以这么用
template <class F>
class Function
问题是这样的话,所有的返回值和参数(个数)信息会全部丢失,这样在Function中的operator()就无法写出合适的调用形式。

一种方式是不用此种函数类型,而用多个模版参数。如
template <class Ret, class Param1>
class Function
此时很容易得到函数的返回值和参数(并且有些Function/Delegate库中确实是这么用的,Boost的可移植类型也是这么干的),但是这么做的话,用户可能看着不习惯。
我们来看看boost是如何做到用一个模板参数同时也可以得到函数类型的返回值和参数个数信息的。
答案就是模板偏特化
在boost中有一个根本未起作用的Function类
template<
typename Signature
>
class function;
但是它有多个偏特化的版本,其中一个如下:
template<typename R,typename P1>
class function<R(P1)>
这个模版偏特化了上述的模版,并且区分出了返回值和参数。嗯,现在我们可以做一个简单的Function看看好不好使

template <typename R, typename P1>
class Function<R(P1)>
{
    typedef R (
*fun)(P1);
public:
    Function()
    {
        m_function 
= NULL;
    }

    Function(fun f)
    {
        m_function 

= f;
    }
    
    R 
operator()(P1 p1)
    {
        
return m_function(p1);
    }
void operator=(fun f)
    {
        m_function 
= f;
    }
private:
    fun m_function;
};
int PrintInt(int i)
{
    printf(
"PrintInt=%d\n",i);
    
return i;
}

Function

<int(int)> fun(PrintInt);int main(int argc, char* argv[])
{
    fun(
20);
    
return 0;
}

代码

template<
typename Signature
>
class Function;

template 

<typename R, typename P1>
class Function<R(P1)>
{
    typedef R (
*fun)(P1);
public:
    Function()
    {
        m_function 
= NULL;
    }

    Function(fun f)
    {
        m_function 

= f;
    }
    
    R 
operator()(P1 p1)
    {
        
return m_function(p1);
    }
void operator=(fun f)
    {
        m_function 
= f;
    }
private:
    fun m_function;
};
int PrintInt(int i)
{
    printf(
"PrintInt=%d\n",i);
    
return i;
}

Function

<int(int)> fun(PrintInt);int main(int argc, char* argv[])
{
    fun(
20);
    
return 1;
}

继续,我们想包装一个类的成员变量,boost推荐的是如下调用方式:

boost::function<int (X*, int)> f;

表示此funtion接受一个类名为X,返回值为int,参数为int的函数。。。嗯,怎么看怎么不爽。。。为啥不用类的成员变量的表达方式呢--- int (FunClass::*)(int) ,也许是很多编译器不支持?

我们看看目前主流C++编译器是否支持此种类型。(vc2008和g++ 4.1.3)偏特化如下代码:

代码

template<
typename Signature
>
class Function;

template 

<typename R, typename P1, class T>
class Function<R (T::*)(P1)>
{
    typedef R (T::
*fun)(P1);
public:

    Function(T 

&t, fun f) : m_class(t)
    {
        m_function 
= f;
    }
    
    R 
operator()(P1 p1)
    {
        
return (m_class.*m_function)(p1);
    }
private:
    T   
&m_class;
    fun       m_function;
};
class FunClass
{
public:
    
int fun(int i)
    {
        printf(
"FunClass fun %d\n",i);
        
return i;
    }
};
int main(int argc, char* argv[])
{
    FunClass funclass;
    Function
<int (FunClass::*)(int)> fun(funclass, &FunClass::fun);
    fun(
123);
    
return 1;
}

哈哈,编译器老老实实通过了,结果也对。