为什么char的数组是模板参数,而const char*可以

发布于 2025-02-01 10:11:19 字数 779 浏览 2 评论 0 原文

我正在尝试将字面字符串作为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'不是有效的模板参数,因为'test :: teststr'是变量,而不是变量的地址

好吧,我不知道这是什么意思。

I'm trying to pass a literal string as a template parameter in a C++14 project. Google told me that I can do as below:

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 did work.

However, if I use const char*, instead of const char []. It won't work.

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>();
}

Now it doesn't work. The compiler told me that 'Test::teststr' is not a valid template argument because 'Test::teststr' is a variable, not the address of a variable.

Well, I don't know what it meant.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烏雲後面有陽光 2025-02-08 10:11:19

编译器的错误消息已经足够清楚:

错误:'test :: teststr'不是有效的模板参数,因为'test :: teststr'是变量,而不是变量的地址

因此您需要:

#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>();
}

然后它的工作 - 要点是,变量的内容不是编译时常数,而可变的地址(如果它是静态或全局变量) 是。

The error message from the compiler is clear enough:

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

So you need:

#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>();
}

And then it works - the point being that [the contents of] a variable is not a compile-time constant, whereas the address of a variable (if it's a static or global variable) is.

清眉祭 2025-02-08 10:11:19

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

模板非类型参数。
对于对象的指针,模板参数必须指定具有静态存储持续时间和链接(内部或外部)

的完整对象的地址

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

全局字符阵列具有链接,而字符串则没有。

在C ++ 20中,这已更改,您可以将字符串文字用作模板参数。

This is just according to the rules of 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

A global array of characters has linkage while a string literal doesn’t.
In C++20 this has been changed and you can use string literals as template parameters.

送舟行 2025-02-08 10:11:19

问题是,在您的示例的情况下,静态数据成员 teststr 是一种指针类型,具有 string字符串文字的地址不允许可以从下面的引用语句中看到,

非类型模板参数的模板 - 应为转换的常数表达式(5.20)
模板参数的类型。对于参考或指针类型的非类型模板参数
常数表达式的价值不得指(或指针类型,不得是地址):

  • (1.1)subobject(1.8),

  • (1.2)临时对象(12.2),

  • (1.3)字符串文字(2.13.5),

因此,在您的示例2 teststr 的情况下,由于它是具有具有指针类型,因此无法使用字符串文字 的地址“ Hello World!”


The problem is that in case 2 of your example the static data member teststr is a pointer type that has the address of a string literal which is not allowed by the standard as can be seen from the quoted statement below ,

From 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),

Thus, in case 2 of your example teststr cannot be used as it is a pointer type that has the address of the string literal "Hello world!".


~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文