我有一个类型morton_id_t
,它是一个64位数字。我有第二种类型,它是Morton ID(morton_id_t
)的位的串联,其中包含几个包含树中级别信息的位:
typedef uint64_t morton_id_t;
typedef uint64_t morton_id_lvl_t;
#define BITS (sizeof(morton_id_lvl_t) * 8)
// number of bits to store the level
#define LEVEL_BITS 6
#define LEVEL_MASK ((1 << LEVEL_BITS) - 1)
// utility functions to pull the level or morton id out of a morton_id_lvl_t
lvl_t level(morton_id_lvl_t n);
morton_id_t morton_id(morton_id_lvl_t n);
// this just strips off the level bits using the `morton_id` function...
bool isAncestor(morton_id_lvl_t ancestor, morton_id_lvl_t descendent);
// ...and calls this
bool isAncestor(morton_id_t ancestor, morton_id_t descendent);
morton_id_t
仅typedef
来自uint64_t
,即使我只需要64 - 6位。
编译器抛出一个错误,说明第二个isAncestor
定义重新定义了第一个,即使类型签名不同。
如何定义两个不同的isAncestor
函数,其中一个函数需要morton_id_lvl_t
,另一个函数需要morton_id_t
?
我是否需要使用课程而不是typedef
?
答案 0 :(得分:5)
morton_id_t
和morton_id_lvl_t
相同,因此isAncestor
签名也是相同的。
typedef
不会创建新类型,而是创建现有类型的别名。
答案 1 :(得分:1)
typedef只为类型引入了一个新名称,不幸的是它没有创建新类型。
您可以将它们包装在结构中以将它们转换为不同的类型:
struct morton_id_t
{
uint64_t id;
};
struct morton_id_lvl_t
{
uint64_t id_lvl;
};
或可能(不是100%确定它是有效的):
struct morton_id_lvl_t
{
uint64_t id:58;
uint64_t level:6;
};
这也可以为您的转化功能提供类型安全。