[英]Implementation of std::is_function with cv-qualifiers and ref-qualifiers
According to the C++ reference , this is a valid implementation of std::is_function
(excluding the partial specializations for variadic functions and noexcept
specifiers for brevity): 根据C ++参考 ,这是std::is_function
的有效实现(不包括可变参数函数的部分专业化,为了简洁起见, noexcept
指定符):
template<class>
struct is_function : std::false_type { };
// specialization for regular functions
template<class Ret, class... Args>
struct is_function<Ret(Args...)> : std::true_type {};
// specialization for function types that have cv-qualifiers
template<class Ret, class... Args>
struct is_function<Ret(Args...)const> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)volatile> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const volatile> : std::true_type {};
// specialization for function types that have ref-qualifiers
template<class Ret, class... Args>
struct is_function<Ret(Args...) &> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const &> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)volatile &> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const volatile &> : std::true_type {};
struct is_function<Ret(Args...) &&> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const &&> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)volatile &&> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const volatile &&> : std::true_type {};
However, using std::is_function
on member functions returns false
: 但是,在成员函数上使用std::is_function
返回false
:
struct X
{
int Test(float)
{
return 0;
}
};
int main()
{
auto x = std::is_function_v<decltype(&X::Test)>; // x is 'false'
return 0;
}
As far as I understand it, cv-qualifiers and ref-qualifiers are only applicable to class member functions. 据我了解,cv限定词和ref限定词仅适用于类成员函数。
So my question is, why does the implementation of std::is_function
specialize for all the different cv-qualifiers and ref-qualifiers when it doesn't consider member functions "functions" to begin with? 所以我的问题是,当std::is_function
的实现不考虑成员函数“ functions”开头时,为什么它专门针对所有不同的cv限定词和ref限定词?
Based on the answer below, I decided to do an experiment. 根据下面的答案,我决定做一个实验。 I implemented my own minimal version of std::is_function
: 我实现了自己的最小版本的std::is_function
:
template <class T>
struct IsFunction :
std::integral_constant<bool, false>
{
};
template <class R, class... A>
struct IsFunction<R(A...)> :
std::integral_constant<bool, true>
{
};
template <class T>
constexpr bool IsFunctionV = IsFunction<T>::value;
And then I changed the signature of X::Test
: 然后我更改了X::Test
的签名:
struct X
{
int Test(float) const
{
return 0;
}
};
Using the function_traits
struct provided in the answer, then I tried this: 使用答案中提供的function_traits
结构,然后尝试了此操作:
auto x = IsFunctionV<function_traits<decltype(&X::Test)>::type>;
In this case, x is false. 在这种情况下, x为假。 But if I add a specialization for const to my IsFunction
as such: 但是,如果我像这样向我的IsFunction
添加const的IsFunction
:
template <class R, class... A>
struct IsFunction<R(A...) const> :
std::integral_constant<bool, true>
{
};
Then x will be true ! 那么x将为真 ! So the overload is important. 因此,过载很重要。 But I'm not sure I understand why, or how function_traits
ends up converting a "member function pointer" to a "member function", which isn't really the same as a regular function, is it...? 但是我不确定我理解为什么,或者function_traits
最终如何将“成员函数指针”转换为“成员函数”,这与常规函数并不完全相同,是吗?
As far as I understand it, cv-qualifiers and ref-qualifiers are only applicable to class member functions. 据我了解,cv限定词和ref限定词仅适用于类成员函数。
Although non-member functions cannot have cv-qualifiers or ref-qualifiers, function types can still contain them without being bound to a specific class type. 尽管非成员函数不能具有cv限定符或ref限定符,但函数类型仍可以包含它们而不绑定到特定的类类型。
typedef void fc() const;
struct S { fc f; };
void S::f() const { }
Here, std::is_function_v<fc>
is supposed to be true
. 在这里, std::is_function_v<fc>
应该是true
。
This is not a direct answer to the question but shows how you can remove the class from the member function type. 这不是问题的直接答案,而是说明了如何从成员函数类型中删除该类。
You can remove the class instance from the member function by a simple type trait to make the function compatible with is_function
. 您可以通过简单的类型特征从成员函数中删除类实例,以使该函数与is_function
兼容。 This is clearly necessary because 这显然是必要的,因为
Types like
std::function
, lambdas, classes with overloadedoperator()
and pointers to functions don't count as function types. 诸如std::function
,lambdas,具有重载operator()
以及指向函数的指针之类的类型均不算作函数类型。http://en.cppreference.com/w/cpp/types/is_function http://en.cppreference.com/w/cpp/types/is_function
#include <iostream>
#include <type_traits>
template < typename T >
struct function_traits { typedef T type; };
template < typename T, typename C >
struct function_traits < T(C::*) > { typedef T type; };
struct X
{
int Test(float)
{
return 0;
}
};
int test(float) { return 1; }
int main()
{
std::cout << std::boolalpha;
auto x = std::is_function< decltype(&X::Test) >::value;
std::cout << x << '\n';
auto y = std::is_function< function_traits<decltype(&X::Test)>::type >::value;
std::cout << y << '\n';
auto z = std::is_function< function_traits<decltype(test)>::type >::value;
std::cout << z << '\n';
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.