【发布时间】:2017-05-19 02:46:37
【问题描述】:
根据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-qualifiers 和 ref-qualifiers 而不考虑成员函数“函数”?
更新:
根据下面的答案,我决定做一个实验。我实现了自己的最小版本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 为假。但是,如果我将 const 的专业化添加到我的 IsFunction 中:
template <class R, class... A>
struct IsFunction<R(A...) const> :
std::integral_constant<bool, true>
{
};
那么 x 将是 true!所以过载很重要。但我不确定我理解为什么,或者function_traits 最终如何将“成员函数指针”转换为“成员函数”,这与常规函数并不相同,是不是......?
【问题讨论】:
-
这不是您要求的功能。您只匹配带有
R(*)(Args...)的函数,但成员函数实际上是R(C::*)(Args...)类型。 -
是的,我知道
std::is_member_function_pointer可用于检查成员函数。不过,不确定“这不是您要求的功能”是什么意思。调用std::is_function_v<decltype(&X::Test)>计算结果为false。这不是我的要求。这就是标准的行为方式。问题是为什么is_function的标准实现专门针对成员函数限定符,无论如何它对成员函数的求值结果为 false,而不管限定符如何。 -
它在哪里专门针对成员函数限定符?
-
检查我上面粘贴的来自cppreference.com的有效实现的sn-p。
const和volatile函数限定符,以及&和&&限定符,以及它们的所有组合都有一个专门化。
标签: c++ typetraits