将具有不同类型的向量作为初始化列表传递给函数

时间:2018-04-15 20:19:12

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

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

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<Member>作为参数。
  2. 此向量应直接从初始化列表传递。
  3. Member的第二个参数可以有不同的类型,这里用 union Parameter表示
  4. 如何在MyClass::foo检测哪些类型已通过?
  5. union Parameter中的类型只能是描述的3个。
  6. 我尝试了很多,但由于我是C ++初学者,我没办法取得成功。

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

1 个答案:

答案 0 :(得分:2)

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

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

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

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

  • struct通过左值引用获取auto foo( std::vector<Member> & ) -> void,但您希望允许使用临时向量调用此值。在这种情况下,我不会使用参考。我会按价值std::vector<Member>

  • std::vector<Member>将不是有效的初始化程序,因为{ "SomeUint", 32767 }的类型为32767。它可以转换为signed intdouble,编译器将无法确定您想要的那个。您可以将unsigned int写为32767u类型的常量。 (我假设你的unsigned int是一个typedef。)

  

如何在uint检测哪些类型已被传递?

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