gpt4 book ai didi

c++ - is_member_function_pointer 实现

转载 作者:搜寻专家 更新时间:2023-10-31 00:19:07 27 4
gpt4 key购买 nike

我正在尝试实现我自己的 is_member_function_pointer,但遇到了问题。

namespace __implementation
{
// integral_constant
template<typename T, T v>
struct integral_constant
{
static constexpr T result = v;
typedef integral_constant<T,v> type;
constexpr operator T() { return result; }
};
// true_type
typedef integral_constant<bool, true> true_type;
// false_type
typedef integral_constant<bool, false> false_type;
// remove_const
template<typename T> struct remove_const { typedef T type; };
template<typename T> struct remove_const<const T> { typedef T type; };
// remove_volatile
template<typename T> struct remove_volatile { typedef T type; };
template<typename T> struct remove_volatile<volatile T> { typedef T type; };
// remove_cv
template<typename T> struct remove_cv
{ typedef typename remove_volatile<typename remove_const<T>::type>::type type; };
// is_function - ugliness ahead due to variadic functions!
template<typename T, typename... Args> struct is_function : public false_type {};
template<typename T, typename... Args> struct is_function<T(Args...)> : public true_type {}; // normal function
template<typename T, typename... Args> struct is_function<T(Args......)> : public true_type {}; // variadic function
// is_member_function_pointer
template<typename T> struct is_member_function_pointer : public false_type {};
template<typename T, typename Class> struct is_member_function_pointer<T Class::*> : public is_function<T> {};
}
/*
* Short forms: either alias templates or constexpr functions
*/
// remove_const
template<typename T>
using remove_const = typename __implementation::remove_const<T>::type;
// remove_volatile
template<typename T>
using remove_volatile = typename __implementation::remove_volatile<T>::type;
// remove_cv
template<typename T>
using remove_cv = typename __implementation::remove_cv<T>::type;
// is_member_function_pointer
template<typename T>
constexpr bool is_member_function_pointer { return __implementation::is_member_function_pointer<T>::result; }
// is_function
template<typename T>
constexpr bool is_function() { return __implementation::is_function<typename __implementation::remove_cv<T>::type>::result; }

问题出在正常的函数指针上,它们无法像 member_function_pointer 模板那样正常工作。此外,const 成员函数指针不被识别为 member_function_pointer,这很不幸。我该如何修复这个实现?我相信我可以enable_if 一个常规的函数指针特化来解决正常的函数指针问题,但我看不到解决 const 成员函数指针问题的方法(我确实尝试过添加 remove_cv 的和 const 在类型特征定义中无处不在,无济于事)。我可以看到当前的 is_member_function_pointer 不处理 const 类的成员函数,但我不知道我可以使用什么语法魔法来做到这一点。

感谢任何帮助。

最佳答案

有关 Chat 的简短谈话带来了这个简单的解决方案:

// is_member_function_pointer
template<typename T> struct is_member_function_pointer : public false_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...)> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) volatile> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const volatile> : public true_type {};

其中还包括 volatile 的特化。

编辑 正如@Xeo 和@Johannes 指出的那样,我错过了 ref-qualifier(又名 *this 的右值)版本:

template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) &> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const &> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) volatile &> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const volatile &> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) &&> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const &&> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) volatile &&> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const volatile &&> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...)> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) volatile> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const volatile> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) &> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const &> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) volatile &> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const volatile &> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) &&> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const &&> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) volatile &&> : public true_type {};
template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const volatile &&> : public true_type {};

这仍然是可行的。它比疯狂的模板魔法和无数帮助模板恕我直言更清晰。

EDIT2 澄清一下,以上内容都在一个实现命名空间中,并由

包围
template<typename T> constexpr bool
is_member_function_pointer() { return __implementation::is_member_function_pointer<remove_cv<T>>::result; }

remove_cv 是方便的别名模板

template<typenamen T> using
remove_cv = typename __implementation::remove_cv<T>::type;

我想还有其他的,也许更好的方法,但是这个方法至少对读者来说是清楚的,没有任何进一步的 SFINAE 技巧,比如在 libc++ 或 libstdc++ 中应用,恕我直言。

关于c++ - is_member_function_pointer 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8960674/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com