【发布时间】:2021-03-02 13:08:38
【问题描述】:
如下例所示,我需要我的Component 结构能够访问子结构中定义的所有“字段”结构。但我有一些限制:
- 字段必须声明为继承结构的嵌套类型。
- 我无法使用任何像 BOOST 这样的库来解决这个问题
- 理论上可以有无限多个字段
- 每个字段都需要声明为独立结构,以便以后可以引用它并避免与其他布尔字段混淆
Component 和Field 结构的模板参数可以随意修改,只要Field 有其TType 参数即可。重要提示,我使用的是 C++20。
// * CRTP stands for Curiously recurring template pattern
template <typename TCrtp>
struct Component
{
template <typename TType>
struct Field
{
using Type = TType;
using Component = TCrtp;
};
using ComponentType = TCrtp;
// Because TCrtp is the inheriting class, the 'TCrtp::Fields' aka 'TestComponent::Fields' type
// can be accessed from here to do anything I need to
};
struct TestComponent : Component<TestComponent>
{
struct Field1: Field<bool> {};
struct Field2: Field<float> {};
// Problem: Can we find a way to fill this tuple automatically
// either from this class or the parent one without using header tool
// or even macros if this is possible
// The goal here is to avoid the programer that is creating this class to repeat itself
// by having to fill manually this tuple and thus potentially forgetting a field, that would cause him
// some troubles (bugs) later on...
using Fields = std::tuple<Field1, Field2>;
};
不幸的是,C++ 不允许在模板参数中声明类型。
我也已经尝试使用和修改此answer 来生成我的代码,但这里的问题是宏需要考虑 2 个参数而不是一个(一个用于字段名称,一个用于类型),这使得它非常棘手,因为需要相当多的逻辑才能实现我所需要的。
【问题讨论】:
-
你对
MACRO((Field1, bool), (Field2, float))或MACRO((Field1, Field2), (bool, float))还好吗? -
这是一个无法解决的问题。在定义子类之前必须定义超类是 C++ 的基础。因此,您不能在超类之前在 CRTP 中定义子类,在 CRTP 声明中定义父类。这就是 C++ 的工作原理。你必须找到其他方法来设计你的类结构。
-
@Jarod42 是的!只要我不必重复自己并且尊重我的约束,这完全没问题。不过,您的 marco 的第一个版本看起来比第二个更好。
标签: c++ templates nested c++20 variadic