我希望我会清楚自己想做什么。
我想根据提供的对象的属性从数据库中获取数据,然后用检索到的数据填充这些属性。 因此,例如,如果用户定义了一个类
<style>
.is-accordion-submenu-parent[aria-expanded="true"] > a::after{
display: none;
}
</style>
,然后当他调用class Person
{
public:
int Id;
string Name;
};
时,它应该返回MyDatabase.Instance.ExecQuery<Person>()
对象,其中装有信息。
我所做的是:用户应按以下方式定义类:
Person
已定义的宏确保将属性的名称和类型添加到class Person : public DBEntity
{
ENTITIY_PROP(Person , int, Id)
ENTITIY_PROP(Person , string, Name)
};
。
现在,如何根据对象的名称设置对象的属性(请参见_propsMeta
)?
我的初始解决方案
我虽然要添加将属性映射到设置该属性的函数的ExecQuery
,但是我无法对具有不同签名的函数进行map
引用。有任何想法吗?如果您认为我需要更改设计以实现所需功能,请告诉我。
map
答案 0 :(得分:0)
以下是使用boost :: hana的解决方案:
#include <iostream>
#include <string>
#include <unordered_map>
#include <boost/lexical_cast.hpp>
#include <boost/hana/define_struct.hpp>
#include <boost/hana/for_each.hpp>
namespace hana = boost::hana;
// for simplicity I assume that a row is an unordered_map
using row_type = std::unordered_map<std::string, std::string>;
// this is how your users will be defining classes
struct Person {
BOOST_HANA_DEFINE_STRUCT(Person,
(int, Id),
(std::string, Name));
};
struct Car {
BOOST_HANA_DEFINE_STRUCT(Car,
(std::string, Brand),
(int, HorsePower));
};
// convenient function to extract the row's mapped value and set it directly to the target
template <class T>
void set_data(T& target, std::string key, const row_type& row)
{
target = boost::lexical_cast<T>(row.at(key));
}
// this is what your database will be doing
template <class Entity>
Entity extract(const row_type& row)
{
Entity entity;
// accessors provides a tuple of pairs, where the first element of each pair is a "compile-time" string from which you can extract the key
// and the second element is a function which returns a reference to appropriate member
hana::for_each(hana::accessors<Entity>(), [&entity, &row](auto unit)
{
std::string property_name = hana::to<const char*>(hana::first(unit));
set_data(hana::second(unit)(entity), property_name, row);
});
return entity;
}
// and now test it
int main()
{
auto person = extract<Person>({{"Id", "42"},{"Name", "John"}});
std::cout << person.Id << " " << person.Name << std::endl;
auto car = extract<Car>({{"Brand", "BMW"},{"HorsePower", "95"}});
std::cout << car.Brand << " " << car.HorsePower << std::endl;
}
您应该仔细阅读documentation page中的相关功能。