[英]How to use a templated alias or const variable to abbreviate a static const variable?
I am writing an entity component system as an exercise with C++17.我正在编写一个实体组件系统作为 C++17 的练习。 I'd like to have each component type, represented as a struct, to be associated with a unique identifier that may be used as a index into into a vector of bitsets in the component registry as an example.我想让每个组件类型(表示为一个结构)与一个唯一标识符相关联,该标识符可以用作组件注册表中位集向量的索引作为示例。 This works using the templated struct ComponentType
.这使用模板化的结构ComponentType
工作。 However, it feels verbose to write ComponentType<Tag>::type
every time I'd like to get the value.但是,每次我想获取值时都编写ComponentType<Tag>::type
感觉很冗长。 I'd prefer to use something like component_type_t<Tag>
.我更喜欢使用类似component_type_t<Tag>
的东西。 However, compilation fails using a templated alias and the implementation as below, though it compiles, using produces the following output.但是,使用模板化别名和以下实现会失败,尽管它会编译,但使用会产生以下 output。 Is there a better way to go about this?有没有更好的方法来 go 关于这个?
0
1
2
0
0
0
Code:代码:
#include <iostream>
namespace ECS {
struct ComponentTraits {
using component_type = unsigned int;
protected:
static component_type types;
};
using component_type = ComponentTraits::component_type;
component_type ComponentTraits::types = 0;
template<typename Component>
struct ComponentType : public ComponentTraits {
static const component_type type;
};
template<typename Component>
const component_type ComponentType<Component>::type = types++;
template<typename Component>
const component_type component_type_t = ComponentType<Component>::type;
//Components
struct Tag {};
struct Transform {};
struct Mesh {};
// and so on...
////Won't compile
//template<typename Component>
//using component_type_t = ComponentType<Component>::type;
};
int main() {
using namespace ECS;
std::cout << ComponentType<Tag>::type << std::endl;
std::cout << ComponentType<Transform>::type << std::endl;
std::cout << ComponentType<Mesh>::type << std::endl;
std::cout << component_type_t<Tag> << std::endl;
std::cout << component_type_t<Transform> << std::endl;
std::cout << component_type_t<Mesh> << std::endl;
return 0;
}
The reason your templated using
is not compiling because your ComponentType
doesn't hold an alias, it holds variable storage.您using
模板化的原因不是编译,因为您的ComponentType
不包含别名,它包含变量存储。
using component_type = unsigned int;
static const component_type type; // this is not an alias
template<typename Component>
using component_type_t = ComponentType<Component>::type;
To fix that error you need to get its type by using decltype
:要修复该错误,您需要使用decltype
获取其类型:
template<typename Component>
using component_type_t = decltype(ComponentType<Component>::type);
But this raises another problem, component_type_t
never actually holds the value you expect, it actually holds the component_type
which is unsigned int
without any value assigned to it ( since it's an alias ), so when you call:但这引发了另一个问题, component_type_t
实际上从未保存您期望的值,它实际上保存了未分配任何值的unsigned int
component_type
类型(因为它是别名),所以当您调用时:
std::cout << component_type_t<Tag> << std::endl;
std::cout << component_type_t<Transform> << std::endl;
std::cout << component_type_t<Mesh> << std::endl;
It prints 0 because your compiler assigning 0 to uninitialized variables, you should not rely on this, because different compilers may deal with this differently.它打印 0 因为您的编译器将 0 分配给未初始化的变量,您不应该依赖它,因为不同的编译器可能会以不同的方式处理这个问题。
So to fix this, you need to pass the value into a variable rather than pass its type:因此,要解决此问题,您需要将值传递给变量而不是传递其类型:
template<typename T>
component_type component_type_t<T> = ComponentType<T>::type;
And your output will be:您的 output 将是:
0 // Tag
1 // Transform
2 // Mesh
0 // Tag
1 // Transform
2 // Mesh
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.