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

Passing a vector with different types as initializer list to function

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

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种

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


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

你可以很接近 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<Member> & ) -> void 通过左值引用获取 std::vector<Member>,但您希望允许使用临时向量调用它。在那种情况下,我不会使用参考。我会按值取 std::vector<Member>

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

How can I detect in MyClass::foo which types have been passed?

最好的方法取决于您这样做的原因。如果您想根据持有的值执行不同的代码,请使用 visit. If you'd like to conditionally execute code for one type only, use get_if. If you'd just like to check, but do nothing with the value itself, use either index or holds_alternative.