为什么你可以通过使用std::is_const和std::is_reference来实现std::is_function?

90
以下是如何实现std::is_function的方法?
template<class T>
struct is_function : std::integral_constant<
    bool,
    !std::is_const<const T>::value && !std::is_reference<T>::value
> {};

(来自CPP Reference
在这个定义下,对我来说,一个int看起来是一个函数。我错过了什么吗?

10
考虑!is_const部分。 - aschepler
为什么函数类型不能是const?这与可恶的类型有关吗? - jtbandes
5
@jtbandes之所以这样说,是因为在C++中函数是少数不属于对象的元素之一。 - Ayxan Haqverdili
1
我猜这是因为从某种意义上来说它总是常量。 - RiaD
我觉得标题有误导性。"这怎么是一个有效的std::is_function实现?" 似乎更合适。 - val is still with Monica
2个回答

79
让我们按照它们的出现顺序来看条件:
如果const T不是常量(因为函数不是对象,所以const不适用于函数类型),而且T不是引用(由于同样的原因,const也不适用于引用),那么它就是函数类型。 int(或任何其他非函数非引用类型)不适合,因为is_const<const int>::valuetrue

根据C++17 Standard §11.3.5 Functions / section 7:(重点在我这里)

函数声明符中的cv限定符序列的效果与在函数类型之上添加cv限定符不同。在后一种情况下,cv限定符将被忽略。[注意:带有cv限定符序列的函数类型不是cv限定类型; 没有带有cv限定的函数类型。 —注] [...]


6
啊……在 is_const 的部分里我漏掉了 "const",这样就说得通了。 - Rian Quinn

61
在语言中,只有两类类型不能具有const限定:引用类型和函数类型。因此,如果“const T”无法成为const限定类型,则意味着T是函数类型或引用类型。如果您可以排除引用类型,则只剩下函数类型。
请注意,带有cv限定符的函数类型(例如“int(int) const”)不是const限定类型。它是“可憎的函数类型”的一个例子,其唯一真正的用途是组合或分解指向成员函数的类型。类型“int(int) const”不能通过在“int(int)”之上添加const限定来获得。相反,“const”适用于隐含的对象参数。

请问您能否提供一个使用int(int) const的示例用例? - user3882729

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接