2012-01-29 273 views
12

今天,我認爲這將是一個不錯的主意,超載operator<<對於C風格的數組:重載運算符<<數組

template<typename T, size_t N> 
std::ostream& operator<<(std::ostream& os, T(&a)[N]) 
{ 
    os << '{' << a[0]; 
    for (size_t i = 1; i < N; ++i) 
    { 
     os << ',' << ' ' << a[i]; 
    } 
    os << '}'; 
    return os; 
} 

int main() 
{ 
    int numbers[] = {2, 3, 5, 7, 11, 13, 17, 19}; 
    std::cout << numbers << '\n'; 
} 

事實上,這很好地打印{2, 3, 5, 7, 11, 13, 17, 19}。但是,通過提供超載,我不能再打印字符串文字:

std::cout << "hello world\n"; 

error: ambiguous overload for 'operator<<' in 'std::cout << "hello world\012"' 
note: candidates are: 

note: std::basic_ostream<_CharT, _Traits>::__ostream_type& 
std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _ 
Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_ 
type = std::basic_ostream<char>] <near match> 

note: no known conversion for argument 1 from 'const char [13]' to 'long int' 

這真是令人費解。爲什麼編譯器甚至在沒有從const char[13]long int首先轉換的情況下考慮過載long int?此錯誤消息的

變化出現long unsigned intshort intshort unsigned intintunsigned intlong long intlong long unsigned int

(其他候選人是const void*const char*const _CharT*,和我自己的模板。)


我提供了唯一的非字符類型的模板解決了這個問題:

template<typename T, size_t N> 
typename std::enable_if< 
    !std::is_same<typename std::remove_cv<T>::type, char>::value, 
std::ostream&>::type operator<<(std::ostream& os, T(&a)[N]) 

但我仍然對編譯器將數字類型視爲候選者的問題感到困惑。

回答

3

重載解析的第一階段是確定可行的函數,這些函數可以接受提供的參數數量(完全忽略類型)。 (見例如13.3.2 [over.match.viable])。

然後,將考慮任何需要的轉換以確定哪一個是唯一的最佳可行功能。

在這種情況下,沒有這種獨特的最佳(有兩個同樣好的候選人)。

錯誤消息可能會告訴你兩個不明確的情況。但我認爲他們試圖通過說明爲什麼所有其他可行的功能都失效了。有時候這很有用,當你不知道爲什麼你想要調用的函數沒有被考慮。

但我同意大多數情況下它只是很多噪音,特別是對於像operator <<operator >>(或甚至operator [])這樣的函數,它們有很多超載。

1

編譯器拒絕程序是正確的。我認爲關鍵是你的超載和ostream::operator<<(char const *)都出現在錯誤信息中。整數可能是一個紅色的鯡魚......你可以reinterpret_cast指針(或字符串文字)到long int(§5.2.10/ 4),但這絕對不是一個標準的轉換。也許編譯器只是試圖通過給你更多的重載來幫助你。

鑑於您的超載和ostream成員,重載解決失敗僅僅因爲沒有優先規則來決定它們(第13.3.1.2節)。因此,由於char const *成員超載是唯一可能與之衝突的成員,因此您的修復似乎很合適。

+0

'std :: ostream'是對類的引用。 – Mankarse 2012-01-29 11:04:41