gpt4 book ai didi

c++ - 指针非类型模板参数

转载 作者:行者123 更新时间:2023-12-02 19:32:16 26 4
gpt4 key购买 nike

我真的不明白为什么下面的代码不能编译:

template<const char*>
struct Foo{};

constexpr const char s1[] = "test1";
constexpr const char* const s2 = "test2";

int main()
{
Foo<s1> foo1; // ok
// Foo<s2> foo2; // doesn't compile
}

取消注释 main() 中的最后一行会使 g++ 和 clang++ 发出错误

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

error: non-type template argument for template parameter of
pointer type 'const char *' must have its address taken

分别。

我的问题是:

  1. 为什么s1实例化可以,而s2实例化不行?
  2. 在任何理智的情况下,此类指针非类型模板参数是否有用?

最佳答案

在上面的评论中,vsoftco 补充道:

seems extremely weird, afaik string literals are not temporaries but are stored for the whole duration of the program, so their address is for sure a compile time constant (or at least that's what I believe)

确实如此。但是,该标准没有指定字符串文字是否具有唯一地址

一些链接器会合并或删除重复的字符串文字。我曾在 "ello" == "hello"+1 的系统上工作过实际上评估为 true 。其他链接器太愚蠢了 "hello" foo.cc 中的地址与 "hello" 不同在 bar.cc 中。哎呀,一些小型 C 编译器是如此愚蠢,以至于 "hello"同一翻译单元内可以有两个不同的地址!

对于这样一个愚蠢的链接器(或编译器),应该 Foo<"hello">导致一个或两个实例化?那就是...

const char *sa = "hello world";
const char *sb = "hello world";
assert(sa != sb); // this assertion is permitted to succeed

template<char*> struct F {};
F<"hello world"> fa;
F<"hello world"> fb;
assert(!is_same<decltype(fa), decltype(fb)>::value);
// should we permit this assertion to succeed also?

委员会令人钦佩地拒绝打开这个蠕虫 jar ,只是简单地禁止了该构造。

<小时/>

现在,可以想象(对我来说,目前)委员会在未来的某个时候可以强制要求所有字符串文字都通过当前用于 inline 的实现所使用的相同机制进行重复数据删除。和template功能。也就是说,我们可以想象一个源级转换,变成

const char *sc = "yoo hoo";

进入

inline auto& __stringlit_yoo_x20hoo() {
static const char x[] = "yoo hoo";
return x;
}
const char *sc = __stringlit_yoo_x20hoo();

那么就只有一个 __stringlit_yoo_x20hoo 的实例(并且只有该函数的静态数组 x 的单个实例)在程序中的任何位置,因此 F<"yoo hoo"> 的含义会是明确的。实现也必须明确地对事物进行名称修改,但是一旦您已经致力于对诸如 F<1+1> 这样的名称进行修改,这就是一个简单的问题。和F<FruitType,ORANGE> (C++ 编译器一直在这样做)。

...但是,您仍然会遇到那些允许的极其智能的链接器(如我所研究的链接器)的问题

assert("hello" == "hello\0world");  // this assertion is permitted to succeed

assert(!is_same_v< F<"hello">, F<"hello\0world"> >);
// should we permit this assertion to succeed also?
// Surely this way lies madness.

关于c++ - 指针非类型模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59824989/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com