C++17之字符串作为模板参数

30 篇文章 17 订阅

    随着时间的推移,c++的不同版本放宽了用作模板参数的规则,而在c++ 17中,这种情况再次发生。现在可以使用模板,而不需要在当前范围之外定义它们。

    非类型模板参数只能是常量整数值(包括枚举)、指向对象/函数/成员的指针、指向对象或函数的lvalue引用,或者std::nullptr_t (nullptr的类型)。

    对于指针,需要链接,这意味着不能直接传递字符串文本。但是,自从c++ 17起,可以使用具有内部链接的指针。例如:

#include <iostream>

template<const char* str>
class Message
{
public:
	Message() :length{ std::strlen(str) }
	{
	}

private:
	std::size_t length{ 0 };
};

extern const char hello[] = "external linkage"; // external linkage
const char hello11[] = "internal linkage!"; // internal linkage

int main()
{
	Message<hello> msg; // OK (all C++ versions)
	Message<hello11> msg11; // OK since C++11

	static const char hello17[] = "no linkage"; // no linkage

	Message<hello17> msg17; // OK since C++17

	return 0;
}

结果如下:

也就是说,自从c++ 17起,仍然需要两行代码来将字符串文本传递给模板。但是可以将第一行放在与类实例化相同的范围内。

这个特性还解决了一个不幸的约束,从c++ 11起虽然可以传递一个指针到类模板,如下:

template<int* p> struct A 
{
};

int num;
A<&num> a; // OK since C++11

但是不能用编译时的constexpr函数返回的地址,C++17中已经支持了:

int num;
...
constexpr int* pNum() {
return &num;
}
A<pNum()> b; // ERROR before C++17, now OK

完整例子如下:

#include <iostream>

int num;

template<int* p> struct A
{
};

constexpr int* pNum() 
{
	return &num;
}

int main()
{
	A<&num> a; // OK since C++11
	A<pNum()> b; // ERROR before C++17, now OK

	return 0;
}

结果如下:

由于pNum返回num的地址,所以变量b的类型也是A<&num>。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值