我想为我想要的每种类型生成一个唯一的类型ID。 对于每个编译,此ID 不必不必相同-对于我指定的每种新类型都必须唯一。 我已经想出了两种解决方案。 这是第一个:
template<typename T>
struct TTypeIdentifier
{
private:
static const T* const Identifier;
public:
static constexpr const T* const * GetIdentifier()
{
return &Identifier;
}
};
template<typename T>
const T* const TTypeIdentifier<T>::Identifier = nullptr;
这有效:
struct TestType : public TTypeIdentifier<TestType>
{
};
struct TestType2 : public TTypeIdentifier<TestType2>
{
};
int main()
{
std::cout << TestType::GetIdentifier() << std::endl;
std::cout << TestType2::GetIdentifier() << std::endl;
return 0;
}
可能的输出为:
00007FF6862E2220
00007FF6862E2228
这是我想出的第二个解决方案:
struct SCounter
{
private:
template<typename T>
friend struct TTypeIdentifier;
static inline size_t Counter { 0 };
};
template<typename T>
struct TTypeIdentifier : private SCounter
{
public:
static constexpr size_t GetIdentifier()
{
static const size_t Identifier = SCounter::Counter++;
return Identifier;
}
};
用法如下:
struct TestType : public TTypeIdentifier<TestType>
{
};
struct TestType2 : public TTypeIdentifier<TestType2>
{
};
int main()
{
std::cout << TestType::GetIdentifier() << std::endl;
std::cout << TestType2::GetIdentifier() << std::endl;
return 0;
}
那里的输出:
0
1
如果您能给我一些建议,那哪种方法更优雅,哪种方法更少,那将非常好。 如果您有更好的解决方案可以提供,那就很好了。
提前谢谢
答案 0 :(得分:1)
除非禁用了RTTI,否则typeid
和std::type_index
是获取类型的唯一ID的最可靠方法。考虑使用它,因为除非为整个项目明确禁用,否则您已经为之付出了全部代价。
如果您坚持使用自己的解决方案,那么我会说第一个更好,因为第二个不编译也不起作用。
那是因为这一行:
static const size_t Identifier = SCounter::Counter++;
首先,您不能在constexpr函数中包含静态数据,其次,您不能使用Counter
本身不是的constexpr
。
第一个解决方案可以进一步改进。拥有一个指向T
的指针的想法,在64位系统上占用8个字节,因此您可以拥有一个较小的数据,仅占用1个字节:
template<typename T>
struct TTypeIdentifier {
static constexpr void const* GetIdentifier()
{
return &Identifier;
}
private:
struct id_t {};
static constexpr id_t Identifier = id_t{};
};
使用id_t
比空指针小得多。
这里唯一的缺点是您不能具有可预测的值,并且它们不是算术值。如果不使用std::less
或标准库提供的其他功能对象,则无法比较它们。任何其他比较器都无法使用。
答案 1 :(得分:0)
您的第一个解决方案既更快又更小。它的GetIdentifier()
方法不执行递增操作,而仅执行return
。它还仅分配一个静态变量(用于指针),而另一个分配两个静态变量。由于size_t
的大小至少等于指针的大小,因此第二个解决方案的分配量是指针的两倍。我再喜欢第一个。