c ++跨编译单元的增量类型ID
c++ incremental type ID across compilation units
我需要每个派生的 class 都有一个唯一的 ID,但 ID 需要是递增的。
这是我当前的实现:
//component.cpp
class ComponentId
{
public:
ComponentId();
static int nextId;
int id;
};
template<class T>
class Component {
public:
static const ComponentId componentId;
};
template<class T>
const ComponentId Component<T, chunkSize>::componentId;
///component.cpp
int ComponentId::nextId = 0;
ComponentId::ComponentId() : id(nextId++)
{
}
//IN static library a
struct compA : public Component<compA> {
}
//In static library b
struct compB : public Component<compB> {
}
//in main.cpp
#include <component.h>
#include <compA.h>
#include <compB.h>
std::cout << compA::componentId.id << std::endl;
std::cout << compB::componentId.id << std::endl;
这在我的所有单元测试中都运行良好,但在使用多个编译单元或跨静态库时似乎无法按预期运行。
ID 在不同的库中重复使用。一个库的 ID 可能为 0、1、2 和 3,但另一个库也将有 class 个 ID 为 0 和 1 的元素。
我的猜测是 nextid 字段没有被共享。
我也尝试过使用 extern 关键字,但它似乎产生了同样的问题。
我也曾尝试制作一个静态 getId 函数,希望在第一次使用时进行初始化,但没有这样的运气。
我确实需要 ID 为 'tight',如 1、2、3、4、5,而不是 67、80、123、1、4。
有什么想法吗?
假设您希望在多个 TU 之间共享一个 int
实例,我认为使用 inline
函数 returns 对 static int
的引用应该可以诀窍:
// counter.hpp
namespace detail
{
inline int& getCounter()
{
static int result{0};
return result;
}
}
inline int nextId()
{
return detail::getCounter()++;
}
// component.cpp
ComponentId::ComponentId() : id(nextId())
{
}
然而,这感觉很脆弱并且容易出错,特别是如果您的目标是 serialization/deserialization 依赖您的 ID。如果您知道 compile-time 处的所有组件类型,我建议使用类型列表。例如
using components = typelist<
Component0,
Component1,
Component2,
Component3
>;
否则,如果您只知道 run-time 处的组件类型,请提供某种允许用户以受控方式 register/unregister 类型的注册表。
我需要每个派生的 class 都有一个唯一的 ID,但 ID 需要是递增的。 这是我当前的实现:
//component.cpp
class ComponentId
{
public:
ComponentId();
static int nextId;
int id;
};
template<class T>
class Component {
public:
static const ComponentId componentId;
};
template<class T>
const ComponentId Component<T, chunkSize>::componentId;
///component.cpp
int ComponentId::nextId = 0;
ComponentId::ComponentId() : id(nextId++)
{
}
//IN static library a
struct compA : public Component<compA> {
}
//In static library b
struct compB : public Component<compB> {
}
//in main.cpp
#include <component.h>
#include <compA.h>
#include <compB.h>
std::cout << compA::componentId.id << std::endl;
std::cout << compB::componentId.id << std::endl;
这在我的所有单元测试中都运行良好,但在使用多个编译单元或跨静态库时似乎无法按预期运行。 ID 在不同的库中重复使用。一个库的 ID 可能为 0、1、2 和 3,但另一个库也将有 class 个 ID 为 0 和 1 的元素。 我的猜测是 nextid 字段没有被共享。
我也尝试过使用 extern 关键字,但它似乎产生了同样的问题。 我也曾尝试制作一个静态 getId 函数,希望在第一次使用时进行初始化,但没有这样的运气。
我确实需要 ID 为 'tight',如 1、2、3、4、5,而不是 67、80、123、1、4。
有什么想法吗?
假设您希望在多个 TU 之间共享一个 int
实例,我认为使用 inline
函数 returns 对 static int
的引用应该可以诀窍:
// counter.hpp
namespace detail
{
inline int& getCounter()
{
static int result{0};
return result;
}
}
inline int nextId()
{
return detail::getCounter()++;
}
// component.cpp
ComponentId::ComponentId() : id(nextId())
{
}
然而,这感觉很脆弱并且容易出错,特别是如果您的目标是 serialization/deserialization 依赖您的 ID。如果您知道 compile-time 处的所有组件类型,我建议使用类型列表。例如
using components = typelist<
Component0,
Component1,
Component2,
Component3
>;
否则,如果您只知道 run-time 处的组件类型,请提供某种允许用户以受控方式 register/unregister 类型的注册表。