- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试实现我自己的 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/
我正在尝试实现我自己的 is_member_function_pointer,但遇到了问题。 namespace __implementation { // integral_constant
我指的是 std::is_member_function_pointer 的可能实现 here . template struct is_member_function_pointer_helper
我正在查看如何仅在函数存在时调用函数的答案,并在这个问题上找到了一些代码 Is it possible to write a template to check for a function's ex
我正在尝试使用 is_member_function_pointer在一个算法中,要么调用一个类型的特定成员函数(如果它存在),要么什么也不做: template struct is_member_f
我有一个模板,其中包含与此类似的声明: template class blah {}; 我有两个版本的模板,当Arg0是成员函数指针时我想使用一个,否则使用另一个。我正在尝试使用 std::enab
我在使用 std::is_member_function_pointer 时遇到问题。据我所知,在给定 noexcept 成员函数时它不起作用。我在标准中找不到任何声明它不适用于 noexcept 合
std::is_member_function_pointer 在 cppreference 上的使用示例使用 & 符号,我在理解语法方面有些困难。 #include class A { v
我正在尝试使用 C++ 中的 SFINAE 来创建一个通用的容器插入器模板函数,我认为考虑以下因素的模板构造 // replace T::nonexistent_member with whateve
我在寻找什么:我有一个模板化类,如果该类具有所需的函数,我想调用一个函数,例如: template do_something() { if constexpr (std::is_member_
我是一名优秀的程序员,十分优秀!