C++ 为什么可以修改在函数中声明的静态常量变量?

C++ 为什么可以修改在函数中声明的静态常量变量?,c++,entity-component-system,C++,Entity Component System,我正在为我的游戏引擎实现一个ECS框架,并研究如何在运行时识别组件类型。这意味着我可以在内存中连续动态分组类似类型的组件。例如,我可以为我的系统可以循环的位置和速度组件使用两个单独的数组 我目前使用的是typeid(),但我遇到了一篇文章,它使用static const变量为每种类型生成唯一的ID。下面的代码片段概括了总体思路: #include <iostream> struct Position { float x, y; }; struct Velocity { float

我正在为我的游戏引擎实现一个ECS框架,并研究如何在运行时识别组件类型。这意味着我可以在内存中连续动态分组类似类型的组件。例如,我可以为我的系统可以循环的
位置
速度
组件使用两个单独的数组

我目前使用的是
typeid()
,但我遇到了一篇文章,它使用
static const
变量为每种类型生成唯一的ID。下面的代码片段概括了总体思路:

#include <iostream>

struct Position { float x, y; };
struct Velocity { float dx, dy; };

template <typename T>
int test(int x) {
    static const int y = x;
    return y;
}

int main(int argc, char **argv) {
    std::cout << test<Position>(1) << " ";
    std::cout << test<Position>(2) << " ";
    std::cout << test<Velocity>(3) << " ";
    return 0;
}
#包括
结构位置{float x,y;};
结构速度{float dx,dy;};
模板
整数测试(整数x){
静态常数y=x;
返回y;
}
int main(int argc,字符**argv){

静态变量只初始化一次

跳过初始化的第二次(以及随后的)时间

这里还有两个不同的函数
test
.1用于每个唯一的模板参数类型

例如,对于代码的简单函数调用:

auto f() { return test<Position>(1); }
auto f(){返回测试(1);}
这将产生以下汇编代码,您可以看到有一个检查来验证变量是否已初始化或返回已设置的值。如果尚未设置,则将以线程安全的方式进行设置

f():
movzx eax,用于int测试的字节PTR保护变量(int)::y[rip]

测试al,al/这里,
静态常量int y=x;
y
常量
表示它是
不可变的
静态
是程序中的存储持续时间

若试图在后续语句中直接修改
y
,编译器将抛出错误,若试图间接修改,则为未定义行为

<>从C++引用,

常量对象-类型为常量限定的对象,或常量对象的不可变子对象。无法修改此类对象:直接尝试这样做是编译时错误,而间接尝试这样做(例如,通过引用或指向非常量类型的指针修改常量对象)导致未定义的行为


有趣的是,C++允许(甚至没有模板),考虑到C没有。“……因为它试图修改常量……”它不是。添加
y=x;
,编译器就会抱怨。@Eljay啊,我很困惑,因为我认为既然静态变量在函数调用后仍然存在,那么再次声明它是非法的,就像在全局范围内执行
静态常量int x=3;静态常量int x=4;