【发布时间】:2019-10-11 16:29:16
【问题描述】:
我想要一个模板函数,它接受某个泛型类型实例的一元成员函数指针。 我的问题是我必须同时支持 void(T val) 和 void(const T& val) 成员函数。
我为每种情况编写了一个模板函数,它工作正常,但这会导致代码重复,因为函数逻辑完全相同。 (我在这里找到了完全相似的东西:Function taking both pointer to member-function and pointer to const member-function,但我没有看到明确的解决方案)。
上面提到的泛型类型的一个例子:
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);
}
【问题讨论】:
-
This close approximation 到您的代码仅使用第一个重载进行编译。不清楚为什么你觉得你需要两者。
-
我没有在函数中包含第三个参数。我很抱歉。我已经修改了代码。现在你应该能够得到错误。我现在也看到了问题(第三个参数类型的 const& 替换),但问题仍然存在。也许是一些特质(我不熟悉特质)。
-
有两个单独的模板参数代替
TPropertyValue- 一个用于setter,一个用于getter。让他们独立推演。 -
这很好用(我现在什至不需要显式类型声明)。谢谢!。然而,它放松了传递给 setter 函数的类型和从 dataReader 返回的类型之间的类型依赖性。在函数中,我调用 dataReader 并在 setter 中传递它的返回值。如果存在类型不匹配,编译器会抱怨,但为了清楚起见,我希望在函数原型上表达这种依赖关系。
-
您可以简单地对类型不匹配进行静态断言...
标签: c++11 templates member-function-pointers