<type_traits>中的is_function_pointer<>是什么?

12

<type_traits>中有以下内容:

is_pointer<>
is_function<>
is_member_function_pointer<>

但不包括这个:

is_function_pointer<>

为什么会这样呢?


2
is_pointer 在函数指针的情况下返回 true,但不适用于成员函数指针。因此 is_member_function_pointer 是必要的补充,而 is_function_pointer 则不是。并不是说它没有用处,只是要提到这个区别。 - Dennis Zickefoose
2个回答

12
[meta.unary.cat]中的特征旨在将每种类型分类为单个类别,例如void、整数、指针等。在这个层次上,函数指针与整数指针没有区别。请注意,成员指针不是指针,只是英语同音词而已。
我们打算让每种类型在[meta.unary.cat]中返回一个true的特征。在这种分类下,函数指针和标量指针都会在is_pointer下返回true。
我要注意的是,我们没有达到我们的目标。nullptr_t超出了我们的目标范围。但我们接近了。这里是当前type_traits分类的图形表示。
更新:
这是一个正确工作且输出正确的程序:
#include <iostream>
#include <type_traits>

typedef void (*fptr)();
typedef int* intptr;

int main()
{
    std::cout << std::is_function<fptr>::value << '\n';
    std::cout << std::is_pointer<fptr>::value << '\n';
    std::cout << std::is_pointer<intptr>::value << '\n';
}

0
1
1

2
函数指针和int*实际上非常不同。(int*)可以通过void*进行可移植的来回转换,但是函数指针不能。 - Ben Voigt
1
@Ben:我认为这是成员函数指针的情况,而不是普通函数指针。但我不确定。 - ildjarn
1
@ildjarn:具有不同代码和数据指针大小的内存模型并不像以前那样普遍(http://en.wikipedia.org/wiki/Intel_Memory_Model),但也并非罕见。许多嵌入式系统具有比数据内存大几个数量级的代码内存,并因此具有不同大小的指针。 - Ben Voigt
2
我怀疑is_function_pointer不存在的原因也是因为有remove_pointer,这使得它可以表示为is_pointer<T> && is_function<remove_pointer<T>>。但对于is_member_function_pointer,则需要remove_member_pointer,但似乎它并不存在。我想知道为什么呢? - Johannes Schaub - litb
啊,我认为这可能会产生歧义。对于 U C::*,它可以产生 UC。我可以想象 remove_member_pointer<T>::class_type 会产生 C,而 remove_member_pointer<T>::type 会产生 U(直观上)。但我可以看出这是有争议的。 - Johannes Schaub - litb
显示剩余2条评论

7

看起来这确实是一个奇怪的疏忽。然而,成员指针始终是成员指针类型,不像自由函数可以是指针类型(void(*)())或函数类型(void())。此外,std::is_pointer从不对成员指针类型返回true。

但是,如果您需要此功能,以下是一种实现方式:

template<typename testType>
struct is_function_pointer
{
    static const bool value =
        std::is_pointer<testType>::value ?
        std::is_function<typename std::remove_pointer<testType>::type>::value :
        false;
};

你的 value 不是一个整数常量表达式。请将该测试放入结构体中,并使 value 成为 const - Xeo

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