根据C++ reference,这是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 {};
但是,对成员函数使用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;
}
据我了解,cv-qualifiers和ref-qualifiers仅适用于类成员函数。
所以我的问题是,为什么std::is_function
的实现专门针对所有不同的cv限定符和ref-qualifiers,因为它不考虑成员函数&#34;函数&#34;开始?
根据下面的答案,我决定做一个实验。我实现了自己的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;
然后我改变了X::Test
的签名:
struct X
{
int Test(float) const
{
return 0;
}
};
使用答案中提供的function_traits
结构,然后我尝试了这个:
auto x = IsFunctionV<function_traits<decltype(&X::Test)>::type>;
在这种情况下, x 为false。但是如果我为我的IsFunction
添加const的特化:
template <class R, class... A>
struct IsFunction<R(A...) const> :
std::integral_constant<bool, true>
{
};
然后x将 true !所以过载很重要。但我不确定我理解为什么,或function_traits
如何最终转换成一个&#34;成员函数指针&#34;一个&#34;成员函数&#34;,它与常规函数真的不一样,是......?
答案 0 :(得分:4)
据我了解,cv-qualifiers和ref-qualifiers仅适用于类成员函数。
虽然非成员函数不能包含cv-qualifiers或ref-qualifiers,但函数类型仍然可以包含它们而不必绑定到特定的类类型。
df['Col1'].update(df['Col2'])
print (df)
Col1 Col2
0 8.0 8
1 9.0 9
2 7.0 7
3 10.0 10
此处,typedef void fc() const;
struct S { fc f; };
void S::f() const { }
应为std::is_function_v<fc>
。
答案 1 :(得分:2)
这不是问题的直接答案,但显示了如何从成员函数类型中删除该类。
您可以通过简单的类型特征从成员函数中删除类实例,以使该函数与is_function
兼容。这显然是必要的,因为
std::function
,lambdas,带有重载operator()
的类和函数指针等类型不算作函数类型。
#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';
}