模板专用化与数组,标准::is_array

template specialisation with arrays, std::is_array

本文关键字:标准 is array 数组 专用      更新时间:2023-10-16

我玩模板专业化和SFINAE。

至于下面的例子,事情似乎很容易:

    template <class T>
    void Do(T t, typename std::enable_if<std::is_integral<T>::value >::type* = 0)
    {
        cout << "is integer" << endl;
    }
    template <class T>
    void Do(T t, typename std::enable_if<std::is_floating_point<T>::value >::type* = 0)
    {
        cout << "is float" << endl;
    }

不,我尝试了std::is_array,但从未使用过std::is_array的专业化。

所以我尝试了为什么is_array永远不匹配:

    template <int num>
    void Do( int a[num])
    {
        cout << "int array size " << num << endl;
    }
    void Do( int* x)
    {
        cout << "int*" << endl;
    }
    ...
    int e[] = { 1,2,3 };
    Do(e);
    ...

对我来说,第一个谜团是,"int a[num]"的专业化从未流行过!函数参数始终具有 int* 类型。

如果我使用引用类型,我得到了"正确"的结果:

    template <int num>
    void Do( int (&a)[num])
    {
        cout << "int array size " << num << endl;
    }
    void Do( int* &x)
    {
        cout << "int*" << endl;
    }

所以我的问题来了:std::is_array 与模板函数参数结合使用是否有合理的用法?我知道那件事

    cout << boolalpha << std::is_array<decltype(e)>::value << endl;

会给我正确的结果。但是手动声明模板选择不会给我任何功能附加。我有什么方法可以检测(有或没有 SFINAE)函数参数的模板专用化是否适合数组?

我想你自己明白了 - 如果你想在分类中使用它们的类型,通过引用将数组传递给模板函数。

要执行此操作的原因是数组到指针衰减,这是模板函数参数在与参数类型匹配之前发生的为数不多的隐式转换之一。这就是为什么当您尝试检查它是否是 DoIt 中的数组类型时,T 是一个指针。但是,当目标类型为引用类型时,不会发生数组到指针衰减。所以,总结一下:

template <class T>
void Do(T& t, typename std::enable_if<std::is_array<T>::value >::type* = 0)

应该工作。

顺便说一句,不使用SFINAE的无聊方式

template <class T, unsigned N>
void Do(T (&t)[N])

也有效。