从tensorflow注册新OP想到的
1,一个小引子
题目如下: 在不改变main函数的情况下,在“hello world!”之前打印一句”12345”
int main()
{
cout << "hello world!" << endl;
return 0;
}
借助C++全局变量在程序开始之后,main函数之前就会初始化的性质,我们可以定义一个 全局变量,并在他的构造函数中打印”12345”
class A
{
pubcli:
A(){
cout << "12345" << endl;
}
};
A a;
//main 函数
如果还要调用其他函数,也可以。比如下面就在A的构造函数里面new了一个B
#include <iostream>
using namespace std;
class B{
public:
B(){ cout << "this is B" << endl; }
};
class A{
public:
A(){
_b = new B();
cout << "12345" << endl;
}
private:
B *_b;
};
A a;
int main()
{
cout << "hello world!" << endl;
return 0;
}
打印结果:
this is B
12345
hello world!
2,注册OP代码分析
下面代码片段和tensorflow注册OP的代码类似:
#include <iostream>
#include <memory>
using namespace std;
class B{
public:
B(){ cout << "this is B" << endl; }
virtual ~B(){}
};
class Regizter
{
public:
Regizter(shared_ptr<B> (*)()){ cout << "this is Regizter with function" << endl;}
Regizter(){ cout << "this is Regizter without param" << endl;}
};
#define OP_CREATER(name, clazz) \
shared_ptr<B> create##name##op() \
{ \
shared_ptr<clazz> ptr = nullptr; \
ptr = make_shared<clazz>(); \
return shared_ptr<B>(ptr); \
} \
Regizter g##name##creater(create##name##op)
//Regizter g##name##creater()
class bn : public B
{
public:
bn(){ cout << "bn" <<endl;}
};
OP_CREATER(BN, bn);
int main()
{
cout << "this is main" << endl;
return 0;
}
上述代码有以下几个理解点:
- ## : 在C++中用于拼接符号,详细信息参考这里
-
OP_CREATER宏 使用该宏将定义一个函数createXXop, 此处的shared_ptr应用于工厂函数,请参看《Effective Modern C++》— Use std::unique_ptr for exclusive-ownership resource management
- Regizter g##name##creater(create##name##op)
以OP_CREATER(BN, bn)为例,这一句宏替换后的形式为: Regizter gBNcreater(createBNop); 可以看出就是定义了一个Regizter类型的全局变量gBNcreater,调用带参的构造函数,所以可以知道上述代码打印结果是:
this is Regizter with function this is main
一个小错误:
如果想使用无参构造函数怎么办?可以看到上面代码注释掉了 Regizter g##name##creater(),然而并没有打印”this is Regizter without param”,这是因为宏展开后,这句只是一个函数声明,Regizter gBNcreater(),而不是一个变量定义,因此把()去掉,就成为了变量定义.