您的位置:首页 > 编程语言

临时函数对象作为函数参数 以及 类模板编程的文件组织

2018-01-13 22:58 417 查看

一、文章要点

1、当临时函数对象作为函数参数时,记住一点:临时对象的返回值是右值,当然临时函数对象的返回值也是右值,此时的形参要么加const,要么用右值引用&&;

2、使用类模版的文件组织:网上的说法是把类的定义以及类中函数的实现放到同一个文件中,然后在主文件中进行引用。还有一种方法是参考gem5的组织方式,把类的定放到一个头文件中,把类中各函数的实现放到令一个头文件中,然后新建一个cpp文件,include上面两个头文件,进行类的显式实例化,这样的话,通过编译过程就能生成类的实例化后的.o文件,这样在主文件中include类定义的头文件,然后就能使用类进行相关的操作了。

二、实例分析:

在学习数据结构与算法的过程中,用到了函数对象,并且需要把临时的函数对象作为参数进行函数间的参数传递。由于书中的例子都是用的模板,并且在类模板中还夹杂着函数的模板。遇到了很多问题,解决了,记录一下。

/*-------------------------------
Platform:code::blocks gcc版本4.9.2
--------------------------------*/

/*------ head.h --------------*/
#ifndef _head_h
#define _head_h

#include <iostream>

template <typename T> class Output{
public:
void operator()(T &e);
};

template <typename T> class Vec{
private:
T _a;

public:
Vec(T a = 0):_a(a){}
template <typename OUT> void print_out(OUT &&);  //使用右值引用,来接收 临时函数对象;
};
#endif // _head_h

/*----- head_impl.h ------------*/
#ifndef _head_impl_h
#define _head_impl_h

#include "head.h"

template <typename T>
void Output<T>::operator()(T &e)
{
std::cout << "通过函数对象调用 进行输出:" << e << std::endl;
}

template <typename T> template <typename OUT>
void Vec<T>::print_out(OUT && out)
{
out(_a);
}
#endif // _head_impl_h

/*------ head.cpp -------------*/
#include "head.h"
#include "head_impl.h"

template class Vec<int>;   //对Vec进行显式的实例化;
template class Output<int>;  //对Output类进行显式的实例化;
template void Vec<int>::print_out<Output<int>>(Output<int> &&); //这儿对 print_out()函数进行显示的实例化;

/*之所以单独对print_out()函数进行实例化,是因为这个函数本身是一个模板函数,通过对Vec的显示实例化,还不能对这个函数进行彻底的实例化,这时候还有函数模板参数这个未知量,所以除了对Vec进行实例化之外,还需要对这个函数单独的实例化,而其他的非模板函数不需要这一步*/

/*------ main.cpp ------------*/
#include <iostream>
#include "head.h"

using namespace std;

int main()
{
Vec<int> v1(8);

v1.print_out(Output<int>());  //这儿使用 临时函数对象作为实参,形参要么使用const,要么使用右值引用;

return 0;
}

输出结果为:
通过函数对象调用 进行输出:8


注:类模板编程的组织挺麻烦的,如果你不想麻烦,那就把类的定义以及类中函数的实现都放在一个头文件中,然后再主程序中直接include这个头文件,这样做的缺点是 编译的文件会很大,会降低编译和链接的速度;
而通过本博客中的这种方法,不会产生巨大的头文件,加快编译速度。而且头文件本身也显得更加“干净”和更具有可读性。但这个方法不能得到惰性实例化的好处,即它将显式地生成所有的成员函数。

参考:关于模板类实例化
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: