在我的游戏引擎的类中,我使用宏为我的成员变量创建元数据。为了能够索引元数据,我使用部分专用的结构,该结构将索引作为第一个参数(请参见下面的示例)。为了专门化结构,我必须声明基本元数据结构,这是通过简单地向前声明结构来实现的。当我使用元数据结构的前向声明继承一个类时,就会出现问题(仅在版本 11 以上的 gcc 中)。我希望这个例子能澄清我的问题。我现在的问题是,gcc 这里是正确的还是编译器错误。如果是这样,有人可以提供解决方法吗?
// Example for METADATA macro, real macro is more complex, but you get the idea.
#define METADATA(type,val,...) \
template<typename field_index, typename... avoid_explicit_specialization> \
struct field_data; \
template<typename... avoid_explicit_specialization> \
struct field_data<std::integral_constant<size_t, __COUNTER__>, avoid_explicit_specialization...>{ /* meta infos */ };
struct Base
{
template<typename field_index, typename... avoid_explicit_specialization>
struct field_data;
//template<typename... avoid_explicit_specialization>
//struct field_data<std::integral_constant<size_t, 0>, avoid_explicit_specialization...>{ /* meta infos */ };
// METADATA(int, var0)
// METADATA(int, var1)
};
struct Derived : Base
{
template<typename field_index, typename... avoid_explicit_specialization>
struct field_data; // ok
//template<typename... avoid_explicit_specialization>
//struct field_data<std::integral_constant<size_t, 0>, avoid_explicit_specialization...>{ /* meta infos */ };
template<typename field_index, typename... avoid_explicit_specialization>
struct field_data; // error
//template<typename... avoid_explicit_specialization>
//struct field_data<std::integral_constant<size_t, 1>, avoid_explicit_specialization...>{ /* meta infos */ };
};
目标:创建一个没有错误的元系统。
一个成员不得在成员规范中声明两次,但以下情况除外
- 可以声明嵌套类或成员类模板,然后再定义,并且
- 可以使用不透明枚举声明引入枚举,然后使用枚举说明符重新声明。
从上面的参考文献中可以看出,我们不允许在 member-specification 中声明两次成员类模板。