C++17完整导引-模板特性之字符串字面量模板参数

字符串字面量模板参数


非类型模板参数只能是常量整数值(包括枚举)、对象/函数/成员的指针、对象或函数的左值引用、 std::nullptr_tnullptr的类型)。对于指针,在 C++17之前需要外部或者内部链接。然而,自从 C++17起, 可以使用无链接的指针。然而, 你仍然不能直接使用字符串字面量
例如:

template<const char* str>
class Message {
    
    
    ...
};

extern const char hello[] = "Hello World!"; // 外部链接
const char hello11[] = "Hello World!";      // 内部链接

void foo()
{
    
    
    Message<hello> msg;     // OK(所有C++标准)
    Message<hello11> msg11; // 自从C++11起OK

    static const char hello17[] = "Hello World!";   // 无链接
    Message<hello17> msg17; // 自从C++17起OK

    Message<"hi"> msgError; // ERROR
}

Message<hello17> msg17;c++11会有如下报错

source>:17:20: error: '& hello17' is not a valid template argument of type 'const char*' because 'hello17' has no linkage
   17 |     Message<hello17> msg17;                        // 自从C++17起OK
      |                    ^

也就是说自从C++17起你仍然需要至少两行才能把字符串字面量传给一个模板参数。
例如 Message<"hi"> msgError;会报如下错误:

<source>:19:17: error: '"hi"' is not a valid template argument for type 'const char*' because string literals can never be used in this context
   19 |     Message<"hi"> msgError;  // ERROR
      |                 ^

然而,你现在可以把第一行写在和实例化代码相同的作用域内。

这个特性还解决了一个不幸的约束:自从C++11起可以把一个指针作为模板实参:

template<int* p> struct A {
    
    
};

int num;
A<&num> a;  // 自从C++11起OK

不能用一个返回指针的编译期函数作为模板实参然而现在可以了

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

猜你喜欢

转载自blog.csdn.net/MMTS_yang/article/details/130772990