【问题标题】:How to have a static counter for global types?如何为全局类型设置静态计数器?
【发布时间】:2020-12-22 23:40:14
【问题描述】:

我想要一个静态计数器,每次创建另一种类型类时都会递增。这是我尝试过的:

template <typename Type>
class Sequential_ID_Dispenser
{public:
    static inline int nextDispensed = 0;
    static int getID() { return nextDispensed++; }
};

struct DummyTypeForComponentIDs {}; // So that the same type is passed to getID()

template <typename T>
struct Component { 
    static inline int componentTypeID = Sequential_ID_Dispenser<DummyTypeForComponentIDs>::getID();
    
    
};

// The reason I've made it inherit like this is so that any time I add a new Component type/struct it'll automatically get an ID for that type
struct Hat : Component<Hat> {};
struct Tie : Component<Tie> {};

int main()
{
    

    int id = Hat::componentTypeID; // = 0
    id = Tie::componentTypeID; // = 1
}

这行得通。但我想选择轻松地从任何其他组件继承,但它不是这样工作的,例如:

template <typename T>
    struct Component { 
        static inline int componentTypeID = Sequential_ID_Dispenser<DummyTypeForComponentIDs>::getID();
   };

    struct Hat : Component<Hat> {};
    struct Tie : Component<Tie> {};
    struct BlueHat : Hat {};

int main()
{
    int id = Hat::componentTypeID; // = 0
    id = Tie::componentTypeID; // = 1
    
    id = BlueHat::componentTypeID; // = 0, gets the same number as struct Hat : Component<Hat>{}
}

有没有好的解决方案?理想情况下,我希望只定义任何新结构而不将参数传递给基本构造函数。我意识到我为此使用了 CRTP,这正是我为使其工作所做的工作,但必须有更简单的方法,对吧?

编辑:实际上我很惊讶解决方案并不容易,我只想为我在全局命名空间中创建的每个类获取一个新 ID,我猜是编译时或运行时。

【问题讨论】:

标签: c++ templates static


【解决方案1】:

您不需要继承类型上的(运行时)计数器。

您甚至可以使用模板变量 (C++14):

std::size_t getId()
{
    static std::size_t counter = 0;
    return counter++;
}

template <typename T>
std::size_t Id = getId();

Demo.

【讨论】:

    【解决方案2】:

    我看不到一个简单的方法来扩展你当前的解决方案来做到这一点,除非你想开始在每个继承声明器上抛出 virtual并记住每次都这样做

    无论如何,“计数类型”似乎有点反模式。我们已经有了唯一的类型标识符,通过typeid

    如果你真的需要int,你可以有一些管理器类,它接受std::type_info,并为你提供该类型独有的int,可能使用映射来支持它。但是,如果您可以首先存储std::type_info,那就更好了。缺点是这些信息不会静态可用(即“在编译时”)。

    【讨论】:

    • 不如 Jarod 的解决方案,但这是否真的有问题?一些有效的替代方法(虚拟继承解决了最初的问题,type_info 识别类型的正确方法)。投反对票似乎有点过分。
    猜你喜欢
    • 2013-10-21
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 2010-12-27
    • 1970-01-01
    相关资源
    最近更新 更多