2016-07-24 93 views
1
#include <string> 
#include <type_traits> 

using namespace std; 

template 
< 
    typename CharT, 
    template<typename> class Traits, 
    template<typename> class Allocator, 
    typename RightT, 
    typename StringT = basic_string 
    < 
    CharT, 
    Traits<CharT>, 
    Allocator<CharT> 
    > 
> 
enable_if_t 
< 
    is_constructible<StringT, RightT>::value, 
    StringT& 
> 
operator <<(StringT& lhs, const RightT& rhs) 
{ 
    return lhs.append(rhs); 
} 

int main() 
{ 
    string s1, s2; 
    s1 << s2; // compilation error! 

    return 0; 
} 

我的編譯器是VS 2015更新3.編譯錯誤信息是:爲什麼不能在std :: string上重載「operator <<」?

錯誤:無效的操作數的二進制表達式( '字串'(又名 'basic_string的,分配器>')和 「串')

爲什麼它不按預期工作?

+3

這正是'operator +'用於 – user4759923

+0

的號碼。它與'operator + ',但類似於'operator + ='。然而,'operator <<'可以:'s1 << s2 << s3 << ...',而'operator + ='不能。 – xmllmx

+0

@xmllmx你爲什麼試圖用模板實際地重載這個? –

回答

4

編譯器給你的信息比單行更多嗎?喜歡的東西:

26:1: note: template argument deduction/substitution failed: 
35:11: note: couldn't deduce template parameter 'CharT' 

如果用

operator <<(basic_string<CharT, Traits<CharT>, Allocator<CharT>>& lhs, const RightT& rhs) 

它編譯取代

operator <<(StringT & lhs, const RightT& rhs) 

基本上你是把車放在馬前面。如果已知道模板參數,則可以使用模板參數形成默認模板參數(StringT = ...。您不能使用默認值來確定參數。

如果你想同時支持basic_string和其他/自定義字符串,你可能需要編寫兩個專門化或其他東西。或者你不需要可構造的,你需要「Appendable」,所以SFINAE就是這樣,而忽略它是basic_string還是MyCustomString - 無關緊要;唯一重要的是lhs.append(rhs)是否可以工作(並且,恩,也許還能算出它的返回類型......)

相關問題