我有这个无工作代码,它应该展示我想要实现的目标:
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 }
}
);
}
我想要实现的目标:
MyClass::foo
需要std::vector<Member>
作为参数。Member
的第二个参数可以有不同的类型,这里用 union Parameter
表示。MyClass::foo
中检测哪些类型已通过?union Parameter
中的类型只能是描述的3个。我尝试了很多,但由于我是C ++初学者,我没办法取得成功。
我正在使用C ++ 17 - Boost不是一个选项。如何实现这一目标?
答案 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 int
和double
,编译器将无法确定您想要的那个。您可以将unsigned int
写为32767u
类型的常量。 (我假设你的unsigned int
是一个typedef。)
如何在
uint
中检测哪些类型已被传递?
最好的方法取决于你做这件事的原因。如果您想根据所持有的值执行不同的代码,请使用visit
。如果您只想有条件地执行一种类型的代码,请使用get_if
。如果您只是想检查,但对值本身不执行任何操作,请使用index
或holds_alternative
。