C++ 将不同类型的向量作为初始值设定项列表传递给函数

C++ 将不同类型的向量作为初始值设定项列表传递给函数,c++,vector,c++17,initializer-list,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:

我有一个不起作用的代码,它应该能证明我想要实现的目标:

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 }
        }
                );
}
类成员
{
const char*someText;
联合参数
{
常量字符*ptr参数;
双双参数;
单位单位参数;
};
};
类MyClass
{
自动foo(std::vector&->void;
};
int main()
{
MyClass实例;
实例.foo(
{
{“SomeText”,“TextParameter”},
{“SomeDouble”,3.14159},
{“SomeUint”,32767}
}
);
}

我想要实现的目标:

  • MyClass::foo
    需要一个
    std::vector
    作为参数
  • 此向量应直接从初始值设定项列表传递
  • 成员
    的第二个参数可以有不同的类型,这里用
    联合参数
    表示
  • 如何在
    MyClass::foo
    中检测已传递的类型
  • 联合参数中的类型只能是上述3种
  • 虽然我尝试了很多,但我没有成功的原因是因为我是C++初学者。

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

    您可以通过以下方法非常接近:

    类成员
    {
    const char*someText;
    std::变量参数;
    };
    
    但您需要进行一些额外的更改,以允许您想要的初始化类型:

    • 字段必须是
      public
      以允许聚合初始化(编译器从
      {a,b}
      进行的内置初始化),但默认情况下
      类型具有
      私有
      字段。在这种情况下,我会将
      class
      更改为
      struct

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

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

    如何在
    MyClass::foo
    中检测已传递的类型


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

    您可以通过以下方法获得非常接近的结果:

    类成员
    {
    const char*someText;
    std::变量参数;
    };
    
    但您需要进行一些额外的更改,以允许您想要的初始化类型:

    • 字段必须是
      public
      以允许聚合初始化(编译器从
      {a,b}
      进行的内置初始化),但默认情况下
      类型具有
      私有
      字段。在这种情况下,我会将
      class
      更改为
      struct

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

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

    如何在
    MyClass::foo
    中检测已传递的类型


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

    C++联合不会跟踪哪个成员处于活动状态。事后无法恢复该信息。作为替代方案对你有用吗?@hvd是的,我必须先检查一下
    union
    在这里只是我想要实现的一个位置。什么是我要使用的要求。C++联盟不跟踪哪个成员是活动的。事后无法恢复该信息。作为替代方案对你有用吗?@hvd是的,我必须先检查一下
    union
    在这里只是我想要实现的一个位置。是的,
    std::variant
    ,在我的例子中,如果解决方案是
    std::get\u,那么它与
    +1.您关于
    uint
    的陈述是正确的。由于在我的项目中,这个参数是一个变量,因此编译器可以赋值并编译它,而不会出错。使用常量失败-我必须附加
    u
    。是的,
    std::variant
    ,在我的例子中,如果解决方案是
    std::get_,那么就加上
    +1.您关于
    uint
    的陈述是正确的。由于在我的项目中,这个参数是一个变量,因此编译器可以赋值并编译它,而不会出错。使用常量失败-我必须附加
    u
    class Member
    {
        const char * someText;
        std::variant<const char *, double, unsigned int> parameter;
    };