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

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

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

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

#include 

template
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 msg; // OK (all C++ versions)
	Message msg11; // OK since C++11

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

	Message msg17; // OK since C++17

	return 0;
}

结果如下:

C++17之字符串作为模板参数_第1张图片

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

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

template struct A 
{
};

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

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

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

完整例子如下:

#include 

int num;

template struct A
{
};

constexpr int* pNum() 
{
	return #
}

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

	return 0;
}

结果如下:

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

你可能感兴趣的:(C++,C++17)