简体   繁体   English

C++17 — 将成员变量的类型映射到 std::optionals

[英]C++17 — mapping types of member variables to std::optionals

How could I take some structure:我怎么能采取一些结构:

template<typename T>
typedef struct something_t {
  int x;
  int y;
  T z;
} something_t;

And create a utility type (possibly combined with some macros) which maps it to the same-shaped structure, but full of std::optionals instead.并创建一个实用程序类型(可能与一些宏组合),将其映射到相同形状的结构,但充满std::optionals In other words, how would I write the partial struct in the following code,换句话说,我将如何在以下代码中编写partial结构,

template<typename T>
struct partial<T> { using type = ??? };

template<typename T>
using partial_something_t = partial<something_t<T>>::type;

...which would result in partial_something_t having this definition: ...这将导致partial_something_t具有以下定义:

template<typename T>
typedef struct partial_something_t {
  std::optional<int> x;
  std::optional<int> y;
  std::optional<T> z;
} partial_something_t;

If you control the definition of something_t , you can change it this way:如果你控制something_t的定义,你可以这样改变它:

template <template<typename> typename Wrapper, typename T>
struct new_something_t {
  Wrapper<int> x;
  Wrapper<int> y;
  Wrapper<T> z;
};

Then define a alias:然后定义一个别名:

template <typename What> 
using Id = What;

Now your original something_t<T> becomes new_something_t<Id, T> and partial_something_t<T> is new_something_t<std::optional, T> .现在你原来的something_t<T>变成new_something_t<Id, T>partial_something_t<T>new_something_t<std::optional, T>

One way to achieve this is to use local includes with macro overloading.实现此目的的一种方法是将本地包含与宏重载一起使用。 Create a new.inl.h file that contains the inner structure some kind this way:以这种方式创建一个包含内部结构的 new.inl.h 文件:

BEGIN_TEMPLATE_STRUCT(something_t)
  DECLARE_MEMBER(int, x)
  DECLARE_MEMBER(int, y)
  DECLARE_MEMBER(T, z)
END_TEMPLATE_STRUCT

Then create maybe two different header files (or only one as you prefer) that define the concrete macro definitions on their own, using push and pop_macro.然后使用 push 和 pop_macro 创建两个不同的 header 文件(或仅一个您喜欢的文件),它们自己定义具体的宏定义。 Place the push_macros right before the include of this.inl.h file with the raw declaration of your struct, include the file and then don't forget to pop_macro to have a clean state afterwards.将 push_macros 放在 this.inl.h 文件的包含结构的原始声明之前,包含该文件,然后不要忘记 pop_macro 之后有一个干净的 state。 Header one then defines BEGIN_TEMPLATE_STRUCT as something_t and header two as partial_something_t and the sub-macros according to your wanted final types (DECLARE_MEMBER as std::optional...). Header 然后定义 BEGIN_TEMPLATE_STRUCT 作为 something_t 和 header 两个作为 partial_something_t 和根据您想要的最终类型的子宏(DECLARE_MEMBER 为 std::optional...)。 The benefit of this approach is, that you have a minimal basic representation of your data that can be adapted to more complex ones.这种方法的好处是,您拥有数据的最小基本表示,可以适应更复杂的数据。 The major drawback is the (error-prone) macro-usage itself and some work to write at least more complex members like method types.主要缺点是(容易出错的)宏使用本身以及一些工作来编写至少更复杂的成员,如方法类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM