You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ECS中通过模板参数生成唯一Component ID的原理咨询

Why static ComponentID typeID{getUniqueComponentID()}; Avoids Duplicate IDs

Great question! This line works because it leverages two core C++ features: template instantiation uniqueness and static local variable initialization rules. Let's break it down step by step.

1. Each Template Parameter Creates a Unique Function Instance

The function getComponentTypeID<T>() is a template function. In C++, every distinct type you pass as T (like A, B, C) generates a completely separate, independent instance of the function.

That means:

  • getComponentTypeID<A>() is a unique function with its own internal state
  • getComponentTypeID<B>() is another distinct function, unrelated to the A version
  • getComponentTypeID<C>() is yet another standalone function instance

Each of these functions has its own copy of the static variable typeID — they don't share this variable across different template instantiations.

2. Static Local Variables Are Initialized Exactly Once

Static local variables (like typeID inside the template function) are initialized only the first time the function is called. After that, the variable retains its value permanently, and subsequent calls to the function skip the initialization step entirely.

Here's how this plays out with your code:

  • When you first call getComponentTypeID<A>():
    • The static typeID is initialized by calling getUniqueComponentID(), which returns 1 (since lastID starts at 1 and increments after returning).
    • typeID is now fixed to 1 for all future calls to this specific function instance.
  • When you first call getComponentTypeID<B>():
    • Its own independent typeID is initialized, triggering another call to getUniqueComponentID() which now returns 2 (since lastID was incremented to 2 after the first call).
    • This typeID stays 2 forever for getComponentTypeID<B>().
  • For getComponentTypeID<C>(), the first call initializes typeID to 3, and every subsequent call just returns that existing 3 without re-running getUniqueComponentID().

3. The Global lastID Ensures Sequential Unique IDs

The getUniqueComponentID() function uses its own static lastID variable, which is shared across all calls. This variable starts at 1, and each time the function is called, it returns the current value and then increments lastID. Since each template function instance only calls this once (during its first initialization), we get a unique, sequential ID for each component type.

Your Code in Action

Let's confirm with your example code (formatted for clarity):

#include <iostream>
using ComponentID = std::size_t;

// Creates a unique ID for each component type (called once per unique component)
ComponentID getUniqueComponentID() noexcept{
    static ComponentID lastID{1u};
    std::cout<< "Created ID: " << lastID << std::endl;
    return lastID++;
}

// Gets the component ID tied to the template type T
template<typename T>
inline ComponentID getComponentTypeID() noexcept{
    // This static variable is unique per template instantiation (A, B, C, etc.)
    static ComponentID typeID{getUniqueComponentID()};
    return typeID;
}

struct A{};
struct B{};
struct C{};

int main(int argc, const char * argv[]) {
    std::cout << getComponentTypeID<A>() << std::endl;
    std::cout << getComponentTypeID<B>() << std::endl;
    std::cout << getComponentTypeID<C>() << std::endl;
    std::cout << getComponentTypeID<C>() << std::endl;
    /* Output:
    Created ID: 1
    1
    Created ID: 2
    2
    Created ID: 3
    3
    3
    */
    return 0;
}

Notice that Created ID: only prints three times (once per unique component type), even though we call getComponentTypeID<C>() twice — the second call just returns the already-initialized 3.

If you added a struct D{}; and called getComponentTypeID<D>() you'd see Created ID: 4 printed once, and the function would return 4 every time after that.

内容的提问来源于stack exchange,提问作者PixelPusher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:38:19