C++14尝鲜:别名模板和变量模板

两种模板(C++03) -> 四种模板(C++14)

传统C++只有两种模板,分别是类模板和函数模板。而最新的C++标准中总共有四种模板,这是因为C++11引入了别名模板,而C++14则引入了变量模板。

别名模板(alias template)

别名模板:带模板参数的类型别名
类型别名(type alias)是C++11新引入的语法形式:
using newtype = oldtype;
在语法功能上,它相当于传统C/C++语言中的typedef语句:
typedef oldtype newtype;
可以看出,类型别名中原有类型和别名的定义顺序与typedef语句正好相反。除此之外,类型别名与typedef语句还有一点不同,类型别名可以加上模板参数形成别名模板:
template<typename ...> using newtype = oldtype<...>;
注:C++11引入类型别名意图取代typedef语句的原因在于:无法直接在typedef语句的基础上直接构建别名模板。这是因为typedef语句自身存在某些局限性,直接给typedef加上模板参数会带来语法解析上的问题。

template<typename T, typename U>
struct A;

template<typename T>
struct B
{
    typedef A<T, int> type;
};

template<typename T>
using C = A<T, int>;

template<typename T>
using D = typename B<T>::type;
代码说明:
  • 假设我们有一个带两个模板参数T和U的类模板A。现在我们需要声明一个只带一个模板参数T的类模板,使其等价于模板参数U为int类型的A模板。也就是说,我们需要一个模板参数T任意,模板参数U为int类型的A模板的别名,或者说A<T, int>的别名。
  • 在C++11之前,答案为类模板B。要定义类型别名,必然要使用typedef。但由于typedef不能带模板参数,所以typedef必须被嵌入到一个带模板参数的类模板里面。在模板参数为T的类模板B里面,类型type被定义成A<T, int>的别名。也就是说typename B<T>::type被定义成了A<T, int>的别名。
  • 在C++11之后,答案为别名模板C。类型别名直接就可以带模板参数。C<T>直接被定义成了A<T, int>的别名。
  • 如果出于某种原因,在定义别名的时候无法使用类模板A而只能使用类模板B,别名模板也能发挥作用。这里D<T>直接被定义成了typename B<T>::type的别名。由于后者是A<T, int>的别名,所以D<T>其实也是A<T, int>的别名。
  • 这段代码展示了别名模板的主要用途:1.为部分模板参数固定的类模板提供别名。2.为类模板中嵌入的类型定义提供别名。

变量模板(variable template)

变量模板:变量的家族
变量模板是C++14新引入的模板形式,在语法功能上它相当于一个没有参数但是有返回值的函数模板,相对于后者,变量模板在语法上更清晰,更能反映编程者的意图。
template<typename ...> type variable;

#include <iostream>
#include <iomanip>
using namespace std;
// 函数模板
template<class T>
constexpr T pi_fn()
{
    return T(3.1415926535897932385);
}
// 变量模板
template<class T>
constexpr T pi = T(3.1415926535897932385);

int main()
{
   cout << pi_fn<int>() << pi<int> << '\n'; // 33
   cout << setprecision(10) << pi<float> << '\n'; // 3.141592741
   cout << setprecision(10) << pi<double> << '\n'; // 3.141592654
}
代码说明:
  • 这段代码所展示的是变量模板的经典用例:圆周率pi。
  • 假设我们需要一个能转成一定数值类型的圆周率。
    如果数值类型为int,圆周率pi就是int(pi)=3。
    如果数值类型为float,圆周率pi就是float(pi)=3.1415927。
    如果数值类型为double,圆周率pi就是double(pi)=3.141592653589793。
  • 在C++14之前,这样的常量只能被定义为函数模板。
  • 在C++14之后,我们可以用变量模板直接定义这样的常量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值