在研究新的 C++ 标准时,我偶然发现了创新的“变量模板”
模板语法如下:
template < typename T >
constexpr T value = T(1234);
关于模板的应用它是这样写的:
此功能允许您创建和使用
constexpr变量模板,以便更方便地与模板算法组合。
我不太明白如何在模板算法中使用这样的变量。你能举一些例子来说明这个机制是如何使用的吗?我也不明白为什么用非模板表达式替换这样的模板表达式是不可能的constexpr,因为我们分别显式地指定了值,并且我们可以显式地编写(推导)类型。
标准中有一个例子:
在这里,变量模板允许您获得所需大小的常量 - 浮点/双精度/等。
另一种流行的用途是作为例如替代
is_some<T>::value品。is_some_v<T>在这里你可以注意到,当声明一个变量模板时,这个变量的类型根本不必匹配模板参数,甚至与模板参数有某种关系。变量模板的大多数琐碎示例通常会赋予变量与模板参数中使用的相同类型的变量,这可能会给人一种错误的印象,即这是必需的。事实上,模板变量可以是任何类型。
例如,以圆的面积为例,您可能决定使用
PI具有特定类型的常量的“基本”定义double然后,使用显式特化,为各个浮动类型添加专门的定义
之后就可以实现一个“单一”的模板函数来计算圆的面积
例如,它将使用整数类型
对于整数类型,
PI带有 type 的“默认”变体将被视为常量double,而对于浮点类型,将使用该常量的特殊值。正如您可能注意到的那样,@Abyx 的答案中的此功能的实现也将“使用”整数类型。但在那个版本中,整数类型的常量 Pi 将得到一个整数值
3,这并不总是可取的。您还可以补充一点,自标准化时代开始以来,C++ 语言中就存在在类模板中包含静态数据成员的能力,即 在 C++98 中。这使得实现“可变模板”成为可能,使用与 C++98 中用于“模板类型定义”的几乎相同的技术,即 通过在模板类的“包装器”中放置类型或变量。特别是,上面的例子可以在经典的 C++98 中实现为
考虑到这一点,模板变量并不是 C++14 的一些基本新特性。它们(简单地说)只是“语法糖”,一种用于编写上述 C++98 实现的更紧凑和优雅的语法。这种情况类似于在 C++11 中引入的声明模板类型定义(通过
using)的可能性,它也可以称为著名的 C++98“模板类型定义”技术的“语法糖”。