c++11 - 模板函数采用指向具有 const& 和按值实现的成员函数的通用指针
问题描述
我想要一个模板函数,它接受一些泛型类型的实例的一元成员函数指针。我的问题是我必须同时支持 void(T val) 和 void(const T& val) 成员函数。
我为每种情况编写了一个模板函数,它工作正常,但这会导致代码重复,因为函数逻辑完全相同。(我在这里发现了完全相似的东西:函数同时使用指向成员函数的指针和指向 const 成员函数的指针,但我没有看到明确的解决方案)。
上面提到的泛型类型的一个例子:
using UserAddress = std::string;
class User
{
private:
int mHeight;
UserAddress mAddress;
public:
void SetHeight(int height){mHeight = height;}
void SetAddress(const UserAddress& address){mAddress = address;}
};
UserAddress
我想通过引用传递一些重型类型在哪里。
我的模板函数:
template <typename TPersistentObject>
class Persistence
{
private:
std::map<std::string, std::function<void(User*)>> mSetterOfProperty;
template <typename TPersistentObject, typename TPropertyValue>
void DefinePropertySettingMethod(const std::string& propertyName,
void (TPersistentObject::*propertySetter)(TPropertyValue), std::function<TPropertyValue(void)> dataReader)
{
mSetterOfProperty[propertyName] =
[propertySetter, columnDataReader](TPersistentObject* persistentObject)
{
(persistentObject->*propertySetter)(dataReader());
};
}
};
/// Const& implementation leading to code duplication
template <typename TPersistentObject, typename TPropertyValue>
void DefinePropertySettingMethod(const std::string& propertyName,
void (TPersistentObject::*propertySetter)(const TPropertyValue&), std::function<TPropertyValue(void)> dataReader)
{
...
}
};
有没有办法定义这个函数来支持以下内容:
int main()
{
auto intDataReader = []() {
return 1;
};
auto stringDataReader = []() {
return UserAddress("Next Door");
};
Persistence p;
p.DefinePropertySettingMethod<User,int>("Height", &User::SetHeight, intDataReader);
p.DefinePropertySettingMethod<User,UserAddress>("Address", &User::SetAddress, stringDataReader);
}
解决方案
感谢Igor Tandetnik的提示,我设法编译了一个解决方案。std::enable_if
不是我需要的,因为我不需要停用过载(或者至少我无法使用它找到解决方案)。
std::conditional
成功了。
这是代码:
#include <string>
#include <functional>
#include <map>
#include <string>
#include <type_traits>
using UserAddress = std::string;
class User
{
private:
int mHeight;
UserAddress mAddress;
public:
void SetHeight(int height){mHeight = height;}
void SetAddress(const UserAddress& address){mAddress = address;}
};
template <typename TPersistentObject>
class Persistence
{
public:
std::map<std::string, std::function<void(TPersistentObject*)>> mSetterOfProperty;
template <typename TPropertyValue>
void DefinePropertySettingMethod(const std::string& propertyName,
void (TPersistentObject::*propertySetter)(TPropertyValue),
std::function<
typename std::conditional<!std::is_same<TPropertyValue, typename std::decay<TPropertyValue>::type>::value,
typename std::decay<TPropertyValue>::type, TPropertyValue>::type
(void)> dataReader)
{
mSetterOfProperty[propertyName] =
[propertySetter, dataReader](TPersistentObject* persistentObject)
{
(persistentObject->*propertySetter)(dataReader());
};
}
};
int main()
{
std::function<int()> intDataReader = []() {
return 1;
};
std::function<std::string()> stringDataReader = []() {
return UserAddress("Next Door");
};
Persistence<User> p;
p.DefinePropertySettingMethod("Height", &User::SetHeight, intDataReader);
p.DefinePropertySettingMethod("Address", &User::SetAddress, stringDataReader);
}
推荐阅读
- symfony - Symfony 4 JWT 身份验证 - 登录前事件监听器
- javascript - 在脚本中导入类
- java - 接受来自控制台以及管道文本文件的 Java 输入
- html - 如何将图像与菜单中的文本放在同一行
- postgresql - Ecto 不会在数据库中插入 :date 字段 - 为什么?
- c# - 是/否 bot framework V4 自适应卡提示问题
- objective-c - 在不知道父键的情况下达到子键 Objective-C
- javascript - 错误“数组:需要参数‘值’”
- sonarqube - 在 jenkinsfile 的容器模板中运行 sonarqube
- javascript - 如何将日期转移到下个月(固定日期)