你可以這樣做:
template <typename T, unsigned int N>
std::ostream & operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
這僅適用於編譯時的陣列,當然。請注意,當T
是內置類型或std
名稱空間中的類型時,不允許您實例化此模板!
如果可能,可能最好使它內聯,因爲每個N
都會導致單獨實例化。 (該pretty printer有這樣的一個例子。)
你會發現,雖然,毯子模板帶來了模棱兩可的,因爲os << "Hello"
現在有兩個可能的過載:模板匹配const char (&)[6]
,和(非模板)過載衰減到指針const char *
,它們都具有相同的轉換序列。我們可以通過禁用我們的字符數組超載解決此問題:
#include <ostream>
#include <type_traits>
template <typename T, unsigned int N>
typename std::enable_if<!std::is_same<T, char>::value, std::ostream &>::type
operator<<(std::ostream & os, const T (&arr)[N])
{
// ..
return os;
}
事實上,會更加普遍,你還可以使basic_ostream
參數模板參數:
template <typename T, unsigned int N, typename CTy, typename CTr>
typename std::enable_if<!std::is_same<T, char>::value,
std::basic_ostream<CTy, CTr> &>::type
operator<<(std::basic_ostream<CTy, CTr> & os, const T (&arr)[N])
{
// ..
return os;
}
鑑於事實T
必須是用戶定義的類型,您甚至可以用is_fundamental<T>
替換is_same<T, char>
以獲得更多檢查(但用戶仍然不能將其用於標準庫類型的數組)。
謝謝,不過我還是要說不明白爲什麼它會導致每個N單獨實例化,如果沒有實現內聯? – Alcott
嗯,它是一個模板,所以每個模板實例最終都可以作爲二進制文件中的一個獨立函數。如果你內聯,你可以完全避免函數調用,儘管這最終取決於編譯器。 –
明白了。用這個運算符<<有2個模板參數,我怎樣才能指定第二個參數N?顯然,我不能僅僅使用「cout << ar;」,我可以嗎? – Alcott