2016-12-02 112 views
4

由于性病::阵列<>和std :: is_array <>双双在C++ 11出台,似乎很奇怪,这不能编译:为什么std :: is_array为std :: array返回false?

#include <array> 
#include <type_traits> 

static_assert(std::is_array<std::array<int,2>>::value); 

有没有一种简单的方法来检查,如果东西是一个数组,包括T[N]std::array<T,N>的可能性?

+2

'std :: array'根本不是数组。他们只是称它为因为它比'std :: array_wrapper'或'std :: better_array'更方便。 – user2357112

+0

@ user2357112:由于'is_array <>'的含义是由定义'array <>'的相同语言的完全相同版本决定的,所以“数组不是数组”的概念看起来很荒谬,不是吗? ? –

+1

智能指针也不会传递'is_pointer'。 'std :: is_array'如果是特殊的'std :: array',将会不太有用,并且使得'std :: array'成为一个真正的数组将首先使得'std :: array'失败。只是不要让名字混淆你。 – user2357112

回答

1

Cppreference提供了这种可能的实现:

template<class T> 
struct is_array : std::false_type {}; 

template<class T> 
struct is_array<T[]> : std::true_type {}; 

template<class T, std::size_t N> 
struct is_array<T[N]> : std::true_type {}; 

它不会对std::array不幸的是提供一个专业化。

template<class T> 
struct is_array : std::is_array<T> {}; 
template<class T, std::size_t N> 
struct is_array<std::array<T, N>> : std::true_type {}; 
+0

该解决方法感觉有点dicey ..可能会打破第三方库头代码取决于包括订单 –

+0

@MM那你有什么建议?直接在'std'内做专门化? – 0x499602D2

+2

我建议你理解'std :: is_array'只是指C风格的数组,而不是'std :: array',如果你想要一个匹配这两个东西的特征,那么就建立你自己的特质 –

4

ISO/IEC 14882:您可以通过这样做,使自己的2011年,第20.9.4.1,表47说,这:

  • 模板:模板结构is_array;

  • 条件:T是已知或未知的程度的阵列类型(3.9.2)

  • 评论:类模板阵列(23.3.2)不是数组类型。

因此,断言应该失败。

虽然您可以按照@ 0x499602D2的建议专门设计is_array,但是如果您这样做了,则应该在另一个名称空间中这样做,因为您不应尝试更改标准化函数的含义。

+0

感谢您的参考。无法使用'std :: is_class <>'区分C++数组与C数组的代码? –

+0

@JohnZwinck是的,它可以。我认为标准作者认为这样会更有用 – harmic

+0

@harmic你的最后一段导致一个格式不正确的程序,不需要诊断; “std”命名空间中traits类的特化不得违反标准中记载的traits类的公理。 – Yakk

1

std::is_array定义为仅适用于类似于T[]T[N]的类型。不包括std::array

根据标准,您不能修改或专用std::is_arraytrue_typestd::array;那会让你的程序不合格,不需要诊断。当std中的类型专门化时,结果必须与标准一致,标准在此处具体说明。 (另外,对于std内的其他模板这样做非常有问题)。

您可以创建自己的is_array特点:

namespace notstd { 
    template<class T> 
    struct is_array:std::is_array<T>{}; 
    template<class T, std::size_t N> 
    struct is_array<std::array<T,N>>:std::true_type{}; 
    // optional: 
    template<class T> 
    struct is_array<T const>:is_array<T>{}; 
    template<class T> 
    struct is_array<T volatile>:is_array<T>{}; 
    template<class T> 
    struct is_array<T volatile const>:is_array<T>{}; 
} 

然后使用notstd::is_array<T>其他地方的检测无论是C风格的数组或C++ std::array

相关问题