2016-12-02 124 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

相關問題