質問

私は、以下の問題を繰り返し処理を行連想配列の文字列を使用して定義され std::map.

-- snip --
class something 
{
//...
   private:
      std::map<std::string, std::string> table;
//...
}

このコンストラクタでは私の読み込みテーブルのペアの文字列のキーに関連する文字列データです。かかる方法 toString この文字列を返しますオブジェクトを含むすべてのキーと関連するデータに含まれるテーブルオブジェクト(key=データ形式)になります。

std::string something::toString() 
{
        std::map<std::string, std::string>::iterator iter;
        std::string* strToReturn = new std::string("");

        for (iter = table.begin(); iter != table.end(); iter++) {
           strToReturn->append(iter->first());
           strToReturn->append('=');
           strToRetunr->append(iter->second());
           //....
        }
       //...
}

がんのようにコンパイルを取得します以下のようなエラー:

error: "error: no match for call to ‘(std::basic_string<char,
    std::char_traits<char>, std::allocator<char> >) ()’".

が誰かに説明しんから、足りないものがありましたら、何なっているが悪いのでしょうか。い一部の議論も同様の問題の場合 hash_map 場所により、ユーザーが定義するハッシュ機能が利用できるように hash_mapstd::string オブジェクト。このようなものでも私の場合は?

役に立ちましたか?

解決

あなたの主な問題は、イテレータにfirst()というメソッドを呼び出しているということです。あなたは何を行うことを意図していることfirstと呼ばれるプロパティを使用します。

...append(iter->first) rather than ...append(iter->first())

スタイルの問題として、あなたはその文字列を作成するためにnewを使用すべきではありません。

std::string something::toString() 
{
        std::map<std::string, std::string>::iterator iter;
        std::string strToReturn; //This is no longer on the heap

        for (iter = table.begin(); iter != table.end(); ++iter) {
           strToReturn.append(iter->first); //Not a method call
           strToReturn.append("=");
           strToReturn.append(iter->second);
           //....
           // Make sure you don't modify table here or the iterators will not work as you expect
        }
        //...
        return strToReturn;
}

編集のfacildelembrarは、近代的なCであなたが今

ループを書き換えることができ++という(コメントで)指摘しました
for (auto& item: table) {
    ...
}

他のヒント

  1. なを書く toString() 方法。これはJava.実施ストリームのオペレーター用クラスです。

  2. 好みの標準アルゴリズムを上書き自分のループを実行します。こうした状況の std::for_each() 提供の素敵なインターフェースだけます。

  3. が発生する場合には、利用、ループなしに変更、データ、。 const_iterator 以上 iterator.そのた場合、誤ってみて、価値観を変え、コンパイラの警告を表示します。

その後:

std::ostream& operator<<(std::ostream& str,something const& data)
{
    data.print(str)
    return str;
}

void something::print(std::ostream& str) const
{
    std::for_each(table.begin(),table.end(),PrintData(str));
}

したいときに印刷で、ストリームのオブジェクト:

int main()
{
    something    bob;
    std::cout << bob;
}

ご必要の文字列表現オブジェクトを利用できます lexical_cast.

int main()
{
    something    bob;

    std::string  rope = boost::lexical_cast<std::string>(bob);
}

の詳細を記入してください。

class somthing
{
    typedef std::map<std::string,std::string>    DataMap;
    struct PrintData
    {
         PrintData(std::ostream& str): m_str(str) {}
         void operator()(DataMap::value_type const& data) const
         {
             m_str << data.first << "=" << data.second << "\n";
         }
         private:  std::ostream& m_str;
    };
    DataMap    table;
    public:
        void something::print(std::ostream& str);
};

あなたの追記が言って呼び出しを変更します。

...append(iter->first)

... append(iter->second)

また、行

std::string* strToReturn = new std::string("");

は、ヒープ上に文字列を割り当てます。あなたが実際にこの動的に割り当てられた文字列へのポインタを返すようにする場合は、リターンははstd ::した文字列を変更する必要があります*。

また、あなたは、ヒープ上にそのオブジェクトを管理心配にローカル宣言を変更したくない場合は、

std::string strToReturn("");

と 'APPEND' を変更する参照構文を使用するために呼び出す...

strToReturn.append(...)

の代わりに

strToReturn->append(...)

これはのコピーは、のそれ戻り変数に、その後、スタック上の文字列を作成することに注意してください。これは、パフォーマンスに影響します。

::イテレータのstd ::マップを間接参照の結果は STDであることに注意してください::ペアに。 firstsecondの値は、彼らが変数であり、関数ではありません。

変更:

iter->first()

タグに
iter->first

iter->secondと同上ます。

iter->firstiter->secondは、あなたはメソッドとしてそれらを呼び出すために、変数しようとしているされます。

使用します。

std::map<std::string, std::string>::const_iterator

の代わりに:

std::map<std::string, std::string>::iterator
11 C ++で使用することができます。

for ( auto iter : table ) {
     key=iter->first();
     value=iter->second();
}

他の価値の最適化は、のLPCTSTRとしての周りに渡すことができる文字列を終了不変NULLを返しSTLののクラス、ののc_str()のメンバーでありますを、E。グラム。、LPCTSTRを期待カスタム関数へ。私はそれを確認するためにデストラクタを通じてトレースしていませんが、私は、文字列クラスは、それがコピーを作成しているメモリの後に見えることを疑うます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top