我有以下代码库:
template <typename Type>
class SomeClass {
public:
template <typename ReturnType, typename... Params>
void register_function(const std::pair<std::string, ReturnType (Type::*)(Params...)> fct) {
auto f = [fct](Params... params) -> ReturnType { return (Type().*fct.second)(std::ref(params)...); }
// ...
}
};
当我将指针传递给成员函数(非const)时,这是有效的。 但是,如果我想传递指向const成员函数的指针,则会导致编译错误,我必须复制上述函数才能获得此代码:
template <typename Type>
class SomeClass {
public:
template <typename ReturnType, typename... Params>
void register_function(const std::pair<std::string, ReturnType (Type::*)(Params...)> fct) {
auto f = [fct](Params... params) -> ReturnType { return (Type().*fct.second)(std::ref(params)...); }
// ...
}
template <typename ReturnType, typename... Params>
void register_function(const std::pair<std::string, ReturnType (Type::*)(Params...) const> fct) {
auto f = [fct](Params... params) -> ReturnType { return (Type().*fct.second)(std::ref(params)...); }
// ...
}
};
现在,我可以传递const-member-functions和non-const-member-functions。但是,现在,代码重复,可维护性降低。
有没有办法将这两个函数合并到一个兼容const-member-functions和non-const-member-functions的函数中?
重要提示:我必须将指针函数作为参数(无std :: function)。
编辑:我添加了更多代码。 在函数内部,我构建了一个与成员函数签名匹配的闭包(相同的返回类型和参数)。 此闭包将被存储并在以后用于进行反射(more here)
答案 0 :(得分:5)
您可以编写一个类型特征,根据该特征将告诉您某些MF
是Type
上的指针成员函数:
template <typename C, typename T>
struct is_pointer_to_member_helper : std::false_type { };
template <typename C, typename T>
struct is_pointer_to_member_helper<C, T C::*> : std::is_function<T> { };
template <typename C, typename T>
struct is_pointer_to_member : is_pointer_to_member_helper<C,
std::remove_cv_t<T>
> { };
并使用它来确保您只获得其中一个:
template <typename Type>
class SomeClass {
public:
template <typename MF>
std::enable_if_t<is_pointer_to_member<Type, MF>::value>
register_function(const std::pair<std::string, MF> fct)
{
auto f = [fct](auto&&... params) {
return (Type{}.*fct.second)(std::forward<decltype(params)>(params)...);
};
// ...
}
};