【c++】模板编程

1、基本概念

#include <iostream> 

// 函数模板
template<typename T>
bool equivalent(const T& a, const T& b)
{
    return !(a < b) && !(b < a);
}

// 类模板(.h)
template<typename T=int> // 默认参数
class bignumber
{
    T _v;
public:
    bignumber(T a) : _v(a) { }
    inline bool operator<(const bignumber& b) const; 	// 等价于 (const bignumber<T>& b)
};
// 在类模板外实现成员函数(.cpp)
template<typename T>
bool bignumber<T>::operator<(const bignumber& b) const
{
    return _v < b._v;
}
 
int main()
{
    bignumber<> a(1), b(1); 							// 使用默认参数,"<>"不能省略
    std::cout << equivalent(a, b) << '\n'; 				// 函数模板参数自动推导
    std::cout << equivalent<double>(1, 2) << '\n';
    std::cin.get();    return 0;
}

1.1 模板类

template <typename T1, typename T2>
struct Test 
{
  T1 t1;
  T2 t2;
};
template <typename T, size_t size>
class Array 
{
public:
	 Array();
	 T &at();
	 size_t size() const;
private:
	 T data_[size];
};

void Demo() 
{
	Array<int, 5> arr; 		// 实例化,并创建对象
	arr.at(1) = 6;
}

1.2 模板函数

// 普通模板函数
template <typename T>
void show(const T &item) 
{
	std::cout << item << std::endl;
}

class Test 
{
public:
	// 模板成员函数
	template <typename T>
	void mem_func(const T &item) {}
};

// 模板lambda表达式(只能是全局变量承载)
template <typename T>
auto f = [](const T &item) {}

调用方法:

show<int>(5);

Test t;
t.mem_func<double>(5.1);

f<char>('A');

1.3 模板全局常量

// 用于引导模板全局常量的模板类(用于判断一个类型的长度是否大于指针)
template <typename T>
struct IsMoreThanPtr 
{
	static bool value = sizeof(T) > sizeof(void *);
};

// 全局模板常量
template <typename T>
constexpr inline bool IsMoreThanPtr_v = IsMoreThanPtr<T>::value;

1.4 变参

1.5 实例化

  • 隐式实例化(implicit instantiation):当使用实例化的模板时自动地在当前代码单元之前插入模板的实例化代码,模板的成员函数一直到引用时才被实例化;
  • 显式实例化(explicit instantiation):直接声明模板实例化,模板所有成员立即都被实例化;

1.6 可变参数

//变参模板函数,第一行为通用,第二行为具体声明
template<typename First, typename... Rest> class tuple;
template<typename... Params> void printf(const std::string &str_format, Params... parameters);

//变参模板类,第一行通用,第二行具体声明
template<typename... Values> class tuple;
tuple<int, std::vector<int>, std::map<<std::string>, std::vector<int>>> some_instance_name;
tuple<> some_instance_name;			//0个实参

//变参个数,sizeof...与sizeof是两个不同的运算符
template<typename ...Args> struct SomeStruct {
    static const int size = sizeof...(Args);
};

可变参数:





https://cppinsights.io/s/b78454ba

#include <tuple>
template<typename... Args>
void f(Args... args) {
    std::tuple<Args...> tup = // 展开模板参数包
        std::make_tuple(args...); // 展开函数参数包
}
int main()
{
    f(1, "2", 3.0);
}
#include <tuple>

template<typename ... Args>
void f(Args... args)
{
  std::tuple<Args...> tup = std::make_tuple(args... );
}

/* First instantiated from: insights.cpp:11 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
void f<int, const char *, double>(int __args0, const char * __args1, double __args2)
{
  std::tuple<int, const char *, double> tup = std::make_tuple(__args0, __args1, __args2);
}
#endif


int main()
{
  f(1, "2", 3.0);
  return 0;
}

c++17:


https://godbolt.org/z/v7PbYh6oP
https://godbolt.org/z/fG5sPE1c3

2、函数作为模板参数

2.1 function_traits

function_traits通过模板特化和可变参数模板来获取函数类型和返回类型
function_traits2 通过对函数特征的学习深入理解模板

2.2 std::function

C++11 function类模板

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值