根据运行时类型实例化构造函数
Instantiating a constructor based on runtime type
在我的工作场所,我正在开发一种在运行时理解类型的产品。出现了一项任务,要求我读取这些类型并根据调用的构造函数将它们存储到 C++ class 中。到目前为止,我已经考虑了 std::tuple
、可变参数模板和 boost::any
的 std::vector
,我可以想出类似
的东西
class Storage
{
private:
std::tuple<int,float,std::string> ti;
public:
Storage(....);
Storage(....);
.... // constructors for all the combinations
};
我们有内部 API 可以告诉我在运行时提供了多少类型,但是,问题是我不知道将以何种方式提供元素,即它可以是只有一种或多于一种或全部三种,依此类推。
因此,我最终得到了一个大的 switch-case 块,我在其中检查了所有输入的可能性(即 1 种类型、2 种类型和 3 种类型)。
有什么办法可以解决这个问题吗?通过一些模板元编程魔法,最终我可以摆脱这个大的 switch-case,只提供一个构造函数,让编译器根据输入实例化构造函数。
我已经回答了 this and this 个问题,但我看不出它如何适合我的用例。
用心打字。如果它不起作用,我不知道是谁写的。我只希望我能正确理解问题。
创建一个包含所有三个成员的辅助结构,以及设置相应成员时设置的三个标志,以及设置成员的重载成员函数:
struct Helper
{
int i;
bool bi;
float f;
bool bf;
std::string s;
bool bs;
void set(int i) { this->i = i; bi = true; }
void set(float f) { this->f = f; bf = true; }
void set(std::string s) { this->s = s; bs = true; }
};
制作一个函数模板(实际上是三个这样的模板)最多接受 3 个参数和 return 一个 Helper
对象:
template<class P1, class P2, class P3> Helper make(P1 p1, P2 p2, P3 p3)
{
Helper h;
h.set(p1);
h.set(p2);
h.set(p3);
return h;
}
template<class P1, class P2> Helper make(P1 p1, P2 p2)
{
Helper h;
h.set(p1);
h.set(p2);
return h;
}
template<class P1> Helper make(P1 p1)
{
Helper h;
h.set(p1);
return h;
}
你的 Storage
class 应该有一个构造函数和一个 Helper
类型的参数,并且只使用设置了标志的参数。要使用系统:
Storage storage = make(<any combination of up to 3 params>);
在我的工作场所,我正在开发一种在运行时理解类型的产品。出现了一项任务,要求我读取这些类型并根据调用的构造函数将它们存储到 C++ class 中。到目前为止,我已经考虑了 std::tuple
、可变参数模板和 boost::any
的 std::vector
,我可以想出类似
class Storage
{
private:
std::tuple<int,float,std::string> ti;
public:
Storage(....);
Storage(....);
.... // constructors for all the combinations
};
我们有内部 API 可以告诉我在运行时提供了多少类型,但是,问题是我不知道将以何种方式提供元素,即它可以是只有一种或多于一种或全部三种,依此类推。
因此,我最终得到了一个大的 switch-case 块,我在其中检查了所有输入的可能性(即 1 种类型、2 种类型和 3 种类型)。
有什么办法可以解决这个问题吗?通过一些模板元编程魔法,最终我可以摆脱这个大的 switch-case,只提供一个构造函数,让编译器根据输入实例化构造函数。
我已经回答了 this and this 个问题,但我看不出它如何适合我的用例。
用心打字。如果它不起作用,我不知道是谁写的。我只希望我能正确理解问题。
创建一个包含所有三个成员的辅助结构,以及设置相应成员时设置的三个标志,以及设置成员的重载成员函数:
struct Helper
{
int i;
bool bi;
float f;
bool bf;
std::string s;
bool bs;
void set(int i) { this->i = i; bi = true; }
void set(float f) { this->f = f; bf = true; }
void set(std::string s) { this->s = s; bs = true; }
};
制作一个函数模板(实际上是三个这样的模板)最多接受 3 个参数和 return 一个 Helper
对象:
template<class P1, class P2, class P3> Helper make(P1 p1, P2 p2, P3 p3)
{
Helper h;
h.set(p1);
h.set(p2);
h.set(p3);
return h;
}
template<class P1, class P2> Helper make(P1 p1, P2 p2)
{
Helper h;
h.set(p1);
h.set(p2);
return h;
}
template<class P1> Helper make(P1 p1)
{
Helper h;
h.set(p1);
return h;
}
你的 Storage
class 应该有一个构造函数和一个 Helper
类型的参数,并且只使用设置了标志的参数。要使用系统:
Storage storage = make(<any combination of up to 3 params>);