2012-02-23 56 views
7

我想爲任意數組重載operator<<,以使代碼cout << my_arr可以工作。首先,我嘗試在const T (&arr)[N]上過載operator<<的第二個參數,其中TN是模板參數。但測試代碼揭示了一個副作用:const char[]也匹配類型規範,並且新的過載與流類中定義的過載衝突。示例代碼:重載算子<<對於數組

#include <cstddef> 
#include <iostream> 

template<typename T, std::size_t N> 
std::ostream& operator<<(std::ostream& os, const T (&arr)[N]) 
{ 
    /* do stuff */ 
    return os; 
} 

int main() 
{ 
    std::cout << "noooo\n"; /* Fails: ambiguous overload */ 
} 

這樣的數組打印操作符仍可以實現嗎?

+0

我不認爲N會在很多情況下良好傳輸。 'void f(int arr [],size_t N){cout << arr; }' – 2012-02-23 21:31:32

+0

如果你想要一個外部庫,爲什麼不使用http://www.boost.org/doc/libs/1_48_0/doc/html/boost_lexical_cast.html – pyCthon 2012-02-23 21:33:33

+1

@Captain:'arr'實際上有'int * '在這種情況下,所以它不會匹配那個過載。 – 2012-02-23 21:49:51

回答

5

肯定的:

template<typename T, std::size_t N> 
typename std::enable_if<!std::is_same<T, char>::value, std::ostream&>::type 
operator<<(std::ostream& os, const T (&arr)[N]) 
{ 
    // ... 
} 

這將禁用過載時Tchar使用SFINAE

對於C++ 03,Boost有enable_ifis_same。或者只是推出自己的:

template<class T, class U> struct is_same { 
    enum { value = false }; 
}; 
template<class T> struct is_same<T, T> { 
    enum { value = true }; 
}; 

template<bool, class T> struct enable_if {}; 
template<class T> struct enable_if<true, T> { 
    typedef T type; 
}; 
+0

任何C++ 03解決方案? – 2012-02-23 21:36:41

+1

@ Mr.Anubis:改用'boost :: enable_if'和'boost :: is_same'。如果你不想要Boost,你自己實現它們,這兩個都是微不足道的。 – 2012-02-23 21:38:00

+0

@GeorgFritzsche:你說得對。但是,它應該是?我猜''const T(&)[]'也可以綁定到一個非const數組,所以是的,寫得很好。它的深層次的'const'不能隱式添加。 – 2012-02-23 22:25:47