为什么 char 数组可以作为模板参数而 const char* 不能

Why can an array of char be a template parameter but a const char* can't

我试图在 C++14 项目中将文字字符串作为模板参数传递。 Google 告诉我可以这样做:

struct Test {
    static const char teststr[];

    template<const char* str>
    void p() {std::cout << str;}
};

const char Test::teststr[] = "Hello world!";

int main() {
    Test t;
    t.p<Test::teststr>();
}

确实有效。

但是,如果我使用 const char*,而不是 const char []。不行。

struct Test {
    static const char* teststr;

    template<const char* str>
    void p() {std::cout << str;}
};

const char* Test::teststr = "Hello world!";

int main() {
    Test t;
    t.p<Test::teststr>();
}

现在不行了。编译器告诉我 'Test::teststr' is not a valid template argument because 'Test::teststr' is a variable, not the address of a variable.

嗯,我不知道是什么意思。

编译器的错误信息很清楚:

error: 'Test::teststr' is not a valid template argument because 'Test::teststr' is a variable, not the address of a variable

所以你需要:

#include <iostream>

struct Test {
    static const char* teststr;

    template<const char **str>
    void p() {std::cout << *str;}
};

const char* Test::teststr = "Hello world!";

int main() {
    Test t;
    t.p <&Test::teststr>();
}

然后是 it works - 关键是变量的 [内容] 不是 compile-time 常量,而变量的地址(如果它是静态或全局变量)是.

这只是根据c++的规则:

Template non-type arguments.
For pointers to objects, the template arguments have to designate the address of a complete object with static storage duration and a linkage (either internal or external)

https://en.cppreference.com/w/cpp/language/template_parameters

全局字符数组具有链接,而字符串文字则没有。
在 C++20 中,这已被更改,您可以使用字符串文字作为模板参数。

问题是,在你的示例的情况 2 中,静态数据成员 teststr 是一个指针类型,其地址为 字符串standard 不允许的文字 从下面引用的语句中可以看出,

来自non-type template parameter's documentation

A template-argument for a non-type template-parameter shall be a converted constant expression (5.20) of the type of the template-parameter. For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):

  • (1.1) a subobject (1.8),

  • (1.2) a temporary object (12.2),

  • (1.3) a string literal (2.13.5),

因此,如果示例 2 teststr 无法使用,因为它是 具有字符串文字地址的指针类型 "Hello world!" .