【问题标题】:Passing a vector with different types as initializer list to function将具有不同类型的向量作为初始化列表传递给函数
【发布时间】:2018-09-25 13:09:26
【问题描述】:

我有这个 没有工作 代码,它应该展示我想要实现的目标:

class Member
{
    const char * someText;
    union Parameter
    {
        const char * ptrParameter;
        double       doubleParameter;
        uint         uintParameter;
    };
};

class MyClass
{
    auto foo( std::vector<Member> & ) -> void;
};

int main()
{
    MyClass instance;

    instance.foo( 
        {
            { "SomeText", "TextParameter" },
            { "SomeDouble", 3.14159 },
            { "SomeUint",   32767 }
        }
                );
}

我想要达到的目标:

  1. MyClass::foo 需要 std::vector&lt;Member&gt; 作为参数。
  2. 此向量应直接从初始化列表传递。
  3. Member 的第二个参数可以有不同的类型,这里用 union Parameter 表示。
  4. 如何检测 MyClass::foo 中的哪些类型已通过?
  5. union Parameter 中的类型只能是描述的这 3 个。

我尝试了很多,但由于我是 C++ 初学者,我没有成功。


我正在使用 C++17 - Boost 不是一个选项。如何实现?

【问题讨论】:

  • C++ 联合不跟踪哪个成员处于活动状态。事后无法恢复该信息。 std::variant 会为你工作吗?
  • @hvd YES,我得先检查一下。 union 在这里只是我想要实现的一个占位符。什么都满足我将使用的要求。

标签: c++ vector c++17 initializer-list


【解决方案1】:

您可以与std::variant 非常接近:

class Member
{
    const char * someText;
    std::variant<const char *, double, unsigned int> parameter;
};

但是您需要进行一些额外的更改才能允许您想要的初始化类型:

  • 字段需要为public 以允许聚合初始化(编译器的内置初始化来自{ a, b }),但class 类型默认具有private 字段。在这种情况下,我会将class 更改为struct

  • auto foo( std::vector&lt;Member&gt; &amp; ) -&gt; void 通过左值引用获取std::vector&lt;Member&gt;,但您希望允许使用临时向量调用它。在那种情况下,我不会使用参考。我会按价值接受std::vector&lt;Member&gt;

  • { "SomeUint", 32767 } 将不是有效的初始化程序,因为 32767 的类型为 signed int。它可以同时转换为doubleunsigned int,编译器将无法确定您想要哪个。您可以编写32767u 来获得unsigned int 类型的常量。 (我假设这就是您的 uint 的类型定义。)

我如何检测 MyClass::foo 中的哪些类型已通过?

最好的方法取决于你这样做的原因。如果您想根据所持有的值执行不同的代码,请使用visit。如果您只想有条件地执行一种类型的代码,请使用get_if。如果您只想检查,但对值本身不做任何事情,请使用 indexholds_alternative

【讨论】:

  • 是的,std::variant 在我的情况下与std::get_if 一起是解决方案。 +1!谢谢
  • 您关于uint 的陈述是正确的。由于在我的项目中这个参数是一个变量,因此编译器可以分配该值并编译它而不会出错。使用常量失败 - 我必须附加 u
猜你喜欢
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-06
  • 2015-08-03
  • 1970-01-01
  • 2023-03-06
相关资源
最近更新 更多