2017-10-21 2 views
3

私はこのコードC++ - 自動鋳造はstd ::文字列にする

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』タイプの右辺のオペランドをとる見つからない(「< <」BINARYまたは 許容される変換はありません)

自動変換は可能ですか、手動でキャストする必要がありますか?

答えて

2

理由は、コンパイラもそれていることがわかりますあなたのクラスから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つのレイヤーが削除され、通常の古いタイプの控除を行ってこの作業を行うことができます。

正しい解決策は、この問題を回避するために、ラッパークラスに挿入演算子を与えることです。

1

あなたは、たとえば、オペレータ< <の適切なオーバーロードを提供する必要があります。すでにoperator<<(std::ostream&, double)が存在するためにも、カスタムoperator<<なく動作t.y

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

しかし、これがなくても二重出力はなぜですか? –

+0

@MartinPerry KeyValuePropertyにはT&への暗黙の変換演算子があります。 –

+1

しかし、この暗黙的な変換がdoubleのために働いている場合、std :: stringではなぜ機能しないのですか? –