c++ - 通用对象实例化
问题描述
我有一堂课:
class User {
public:
int id = 0;
std::string email = "";
User(int id_, std::string email_) :
id(id_), email(email_) {}
};
我可以像这样构造一个实例:
auto x=Model::User({3,"m"});
但是我需要使用来自向量的数据来构造实例。我从数据库中获取这些数据,并希望使对象的构造具有通用性:
auto v=std::vector<std::any>({3,"m"}); // from the db
auto x=Model::User(v); // instanciate the object with a vector, does not work without special constructor.
无需修改类构造函数。是否可以使用参数包或 initializer_list 来做到这一点?
就像是
template<typename T>
T makeobject(vector<any> args) {
// instanciate new object of type T, initialised with data from args
// and return it
}
auto u=makeobject<User>(v);
解决方案
你可能会这样做:
User makeUser(const std::vector<std::any>& args) {
return User(std::any_cast<int>(args[0]), std::any_cast<const char*>(args[1]));
}
由于 C++ 没有反射,要使其通用,您必须为要支持的每个类提供特征(或与magic_get兼容)
template <typename T, typename Tuple, std::size_t...Is>
T makeObject(std::index_sequence<Is...>, const std::vector<std::any>& args) {
return T(std::any_cast<std::tuple_element_t<Is, Tuple>>(args[Is])...);
}
template <typename T>
T makeObject(const std::vector<std::any>& args) {
using Tuple = typename T::TupleConstructor;
return makeObject<T, Tuple>(std::make_index_sequence<std::tuple_size_v<Tuple>>(), args);
}
和
class User {
public:
using TupleConstructor = std::tuple<int, const char*>;
int id = 0;
std::string email = "";
User(int id_, std::string email_) :
id(id_), email(email_) {}
};
可以使用外部 type_traits 代替直接添加别名类型 in User
。
推荐阅读
- c++ - 如何将 const wchar_t 类型转换为 LPTSTR (C++)
- python - 在 Class 中存储表格数据
- laravel - Axios 请求已被 cors 阻止,请求的资源上不存在“Access-Control-Allow-Origin”标头
- android - 在颤动中结合两个不同的firebase集合
- javascript - 让 babel 自动转译
- javascript - 从 api 获取新数据
- javascript - 如何在反应js中传递一个函数来形成输入值?
- haskell - 在用户定义类型和现有类型之间定义已经存在(例如在 Prelude 中)运算符的正确方法是什么?
- scala - 具有案例等级评级的 ALS 训练数据
- python - Pandas 中的线性模型