2017-10-21 44 views
3

我有這樣的代碼C++ - 汽車鑄件的std :: string

template <typename T> 
class KeyValueProperty { 
protected: 
    T value = T(); 
    std::string key = ""; 

public: 
    KeyValueProperty(const std::string & key) : key(key) { } 

    T & operator = (const T &i) { return value = i; };  

    operator const T &(){ return value; };  
}; 


struct T2 { 
    KeyValueProperty<std::string> x {"x"}; 
    KeyValueProperty<double> y {"y"}; 
}; 

,並在主

T2 tx; 
tx.x = "hellow";  
tx.y = 10; 

std::cout << static_cast<std::string>(tx.x) << ::std::endl; 
std::cout << tx.y << ::std::endl; 

這是正常工作。但是,這樣做只是這

std::cout << tx.x << ::std::endl; 

將在

錯誤C2679結束:二進制「< <」:沒有操作員發現這需要類型的右手操作數‘測試:: KeyValueProperty’(或 沒有可接受的轉換)

是否有可能進行自動轉換,或者我必須手動調用鑄造?

回答

2

t.y即使工作沒有定製operator<<是因爲已經存在的operator<<(std::ostream&, double)的原因,編譯器也可以看到它可以讓你的班級脫離double。它這樣做,我們很高興。

但是,沒有operator<<(std::ostream&, std::string)。如果有的話,同樣的邏輯將適用,我們仍然會很高興。取而代之的是:

template <class CharT, class Traits, class Allocator> 
std::basic_ostream<CharT, Traits>& 
    operator<<(std::basic_ostream<CharT, Traits>& os, 
       const std::basic_string<CharT, Traits, Allocator>& str); 

也就是說,對於任何形式的basic_string通用插入運算符。

儘管存在一些模板參數會使它看起來好像是operator<<(std::ostream&, std::string),但編譯器不會嘗試猜測哪些可能的模板參數會允許它隨後將您的類轉換爲結果。組合太多,所以這是不允許的。

這就是爲什麼你必須明確地把你的對象轉化爲std::string(又名std::basic_string<char>) - 這將刪除問題的一個層,它可以做普通的舊型扣,使這項工作。

正確的解決方案是給你的包裝類一個插入操作符來回避這個問題。

1

您必須提供運營商< <適當超載,例如:

template<class T> 
std::ostream& operator<<(std::ostream& os, KeyValueProperty<T> const& kvp) 
{ 
    return os << T(kvp); 
} 
+1

但是,即使沒有這個,爲什麼雙重輸出呢? –

+0

@MartinPerry KeyValueProperty對T&隱式轉換運算符。 –

+1

但是,爲什麼這個隱式轉換對於std :: string不起作用,如果它是用於double的呢? –