2012-04-23 13 views
10

編集:Mike Seymourのコメントに続いて、operator std::string() const;operator char *() const;に置き換え、それに応じて実装を変更しました。これは暗黙的なキャストを可能にしますが、何らかの理由でunsigned long int演算子がchar *演算子よりも優先されます。ちょうどいい感じではありません...また、char *のような厄介なCのものを公開したくありませんクラス、私はstd :: stringを持っています。私は、私の望む機能をサポートするために、私のCustomizedIntクラスがいくつかのものから継承する必要があることに感心しています。誰でもstd::basic_stringに関するマイクのコメントを詳しく教えてもらえますか?私はそれを正しく理解しているか分からない。C++暗黙の変換演算子先行


私は、コードのこの部分があります: "演算子のunsigned long int型と呼ばれる; 123" プリント

#include <string> 
#include <sstream> 
#include <iostream> 

class CustomizedInt 
{ 
private: 
    int data; 
public: 
    CustomizedInt() : data(123) 
    { 
    } 
    operator unsigned long int() const; 
    operator std::string() const; 
}; 

CustomizedInt::operator unsigned long int() const 
{ 
    std::cout << "Called operator unsigned long int; "; 
    unsigned long int output; 
    output = (unsigned long int)data; 
    return output; 
} 

CustomizedInt::operator std::string() const 
{ 
    std::cout << "Called operator std::string; "; 
    std::stringstream ss; 
    ss << this->data; 
    return ss.str(); 
} 

int main() 
{ 
    CustomizedInt x; 
    std::cout << x << std::endl; 
    return 0; 
} 

を。私の質問は次のとおりです:

  1. 演算子unsigned long intを削除した後、xをstd :: stringに明示的にキャストする必要があるのはなぜですか?なぜ暗黙のキャスト演算子(std :: string)を直接呼び出さないのですか?
  2. どの暗黙のキャストが許可され、どの優先順位が優先されるかを説明するドキュメントはありますか?これは、演算子unsigned long intと演算子unsigned intを加算すると、< <演算子のコンパイラエラーが表示されるようです...
  3. また、このような演算子を定義することができます貧しい人々の練習ですが、私は関連する警告を十分に理解していません。誰かがそれらの概要を教えてもらえますか?パブリックメソッドToUnsignedLongIntとToStringを定義するほうがよいでしょうか?
+0

これは関連しています:[文字列への暗黙的な変換によるオブジェクトのストリーミング時のオーバーロード解決の失敗](http://stackoverflow.com/questions/6677072/overload-resolution-failure-when-streaming-object-via-implicit-conversion -str) –

+0

@Als:ゆっくりとしましょう...私はまだテンプレートに飛び込むつもりはありません:) –

答えて

8

演算子unsigned long intを削除した後、xをstd :: stringに明示的にキャストする必要があるのはなぜですか?なぜ暗黙のキャスト演算子(std :: string)を直接呼び出さないのですか?

文字列の<<のバージョンはstd::basic_stringテンプレート(std::string自体がそのテンプレートの特殊化である)のパラメータによってparametrised、テンプレートです。それは引数依存ルックアップによってのみ選択することができ、引数が実際にstd::basic_stringの特殊化であり、それが変換可能なものではない場合にのみ機能します。

どの暗黙のキャストが許可され、どの優先順位が優先されるかを説明するドキュメントはありますか?

ルールは非常に複雑で、完全なストーリーについてはC++標準を読む必要があります。簡単な経験則では、暗黙の変換に複数のユーザー定義変換を含めることはできず、暗黙の変換の結果を引数依存ルックアップでテンプレートの特殊化を選択するために使用することはできません。

私は、関連する警告を完全に理解しているかどうかはわかりません。誰かがそれらの概要を教えてもらえますか?

私はそれらを完全に理解していません。暗黙的な変換、名前の検索とテンプレートの特殊化(と私は今考えることができない他の要因かもしれない)間の相互作用はかなり複雑で、ほとんどの人はそれらをすべて学ぶ傾向がありません。暗黙の変換が行われないケースがかなりあります。また、期待しないときに起こる可能性のあるケースもあります。個人的には、ほとんどの場合暗黙的な変換を避けるほうが簡単です。

ToUnsignedLongIntとToStringのパブリックメソッドを定義する方がよいでしょうか?

これは、望ましくないコンバージョンを避けるためのよい考えです。あなたはそれらを残すことによって、あなたの問題を解決し、必要なときに、明示的にそれらを使用することができます:C++ 11では

std::cout << std::string(x) << std::endl; 

、彼らは唯一この方法で使用することができるように、あなたは、explicitそれらを宣言することができます。あなたができるならば、私の意見では、それは最善の選択肢でしょう。それ以外の場合は、明示的な変換関数を使用します。

ところで、返品タイプmain()は、voidではなく、intでなければなりません。

+0

マイク:このような詳細なコメントを提供してくれてありがとう。それは少し物事をクリアします。また、「ボイド・メイン」という小さな問題を発見してくれてありがとう。私は正しいバージョンを使用することを忘れてはならない、どんなに:) –

関連する問題