【问题标题】:C++ Returning a member from one of 2 structs using macros or templatesC ++使用宏或模板从2个结构之一返回成员
【发布时间】:2022-01-17 20:14:29
【问题描述】:

我正在开发一个针对专有 PDK 在主机程序中运行的插件。 PDK 中有时会发生重大更改,因此我的代码使用包装器类,允许它与多个版本的主机一起工作,同时封装不同版本的更改。

这是一个非常简化的示例,说明了我想解决的问题。当然,我正在与更多的成员打交道 2。

struct DataV1 // I cannot modify this
{
   int a;
   float b;
};
struct DataV2 // I cannot modify this
{
   float b;
   int a;
   long c;
};

class DataWrapper // my class
{
private:
   bool _forV1; // determined at run-time
   DataV1 _dataV1;
   DataV2 _dataV2;

public:
   DataWrapper(); // initializes _forV1

   int GetA() const;
   void SetA(int value);
   float GetB() const;
   void SetB(float value);

   long GetC() const { return _dataV2.c } // only exists in v2
   void SetC(long value) { _dataV2.c = value; } // only exists in v2
};

我想避免在每个 getter 和 setter 中重复从结构的一个版本或另一个版本中选择成员的逻辑。请注意,虽然重新排列了成员的顺序,但类型和成员名称是相同的。我想出了这个宏:

#define DATA_ACCESS(MEMBER) const_cast<decltype(_dataV1.MEMBER)&>(([&]() -> const decltype(_dataV1.MEMBER)& \
                                    { return (_forV1) ? _dataV1.MEMBER : _dataV2.MEMBER; })())

这允许对属性访问器函数进行一些优雅的实现:


   int GetA() const { return DATA_ACCESS(a); }
   void SetA(int value) { DATA_ACCESS(a) = value; }
   float GetB() const { return DATA_ACCESS(b); }
   void SetB(float value) { DATA_ACCESS(b) = value; }

我发布这个问题是为了看看是否有人有更好的想法,尤其是不涉及宏的想法。谢谢。

【问题讨论】:

  • 已经有一个包装器:std::variant
  • 我查看了std::variant,但在没有 if 语句的情况下看不到如何在每个 getter 和 setter 中使用它。你有一个在这种情况下我将如何使用它的例子吗?
  • 我不确定我是否完全理解,但也许多态性会有所帮助? idea
  • 我喜欢std::visit 的想法。二传手将如何工作?
  • 我相信您已经找到了std::variant 的文档。因此,您只需阅读文档中的给定示例并根据需要修改代码。有什么理由让我们再次重复这里的示例代码吗?

标签: c++ templates c++17


【解决方案1】:

使用std::variant,您可能会执行以下操作:

class DataWrapper // my class
{
private:
   std::variant<DataV1, DataV2> data;

public:
   DataWrapper(); // initializes _forV1

   int GetA() const { return std::visit([](auto& arg){ return arg.a; }, data); }
   void SetA(int a) const { std::visit([&a](auto& arg){ arg.a = a; }, data); }
    // ...
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多