前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++17常用新特性(十)---模板特性:字符串变量当做模板参数

C++17常用新特性(十)---模板特性:字符串变量当做模板参数

作者头像
CPP开发前沿
发布2022-06-04 17:29:25
1.4K0
发布2022-06-04 17:29:25
举报
文章被收录于专栏:CPP开发前沿CPP开发前沿

在C++的历次版本发布中,对C++模板参数的标准一直保持开放的态度,且对参数的要求也在逐渐放宽。从C++17开始,非类型的模板参数也可以在使用时定义了而不必定义在不同的作用域。

1 在模板中使用字符串

在模板编程中,非类型的模板参数被限制了诸多条件,只能从以下几种类型中获取,如:枚举、对象、指针、常量以及函数的左值引用、字符串变量。对于字符串变量,使用方式和之前的版本并没有太大的区别,都不能直接在模板类型参数中使用。如下面的代码:

代码语言:javascript
复制
template<const char *pMsg>
class ExecptionMsg{
   //... 
};
extern const char execptionMsg[] = "Hello"; // 外 部变量
const char execptionMsg_1[] = " World!"; // 内 部 变量
void foo()
{
    ExecptionMsg<execptionMsg> msg; //编译成功
    ExecptionMsg<execptionMsg_1> msg11; // 从C++11起编译成功
    static const char execptionMsg_2[] = "Hello World!";
    ExecptionMsg<execptionMsg_2> msg17; //C++17 编译成功
    ExecptionMsg<"Hello"> msgError; //编译报错
}

如上代码所示,如果编译时没有注释:

代码语言:javascript
复制
 ExecptionMsg<"Hello"> msgError;

编译将会报错,报错信息如下:

由此可见,在非类型的模板参数中,字符变量是不能直接使用的,在使用之前需要先进行定义。C++17除了继续遵守这个规范外,相对于之前的版本它允许在实例化模板的作用域内声明,然后使用。不得不说也算是一种进步了吧。

2 将指针作为模板实参

从C++11开始,已经允许将指针作为模板的实参,但是还有一个限制,既在模板实例化时不能将一个返回指针的函数当做模板的实参。但是从C++17开始,可以在模板中使用一个返回指针的函数当做实参,如下面的代码在C++17版本编译器中可以通过:

代码语言:javascript
复制
#include <iostream>
using namespace std;
template<int *pMsg>
class ExecptionMsg{
   //... 
};

int iValue=10;
constexpr int *getInt()
{
  
    return &iValue;
}
int main()
{
    static int num=10;
    ExecptionMsg<&num> em;
    ExecptionMsg<getInt()> emf;
    return 0;
}

在C++14版本编译器中编译报错如下:

从报错信息可知,在C++17以前的版本中,使用指针作为模板的实参时需要对参数进行连接且不能将编译器内返回指针的函数在模板实例化时进行使用。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CPP开发前沿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档