1

これは、いくつかのテスト用に作成した以下のプログラムです。

class tgsetmap
{
public:
std::map<std::string,std::string> tgsetlist;
void operator<<(const char *str1,const char *str2)
{
  tgsetlist.insert( std::map<std::string,std::string>::value_type(str1,str2));
}

};


int main()
{

tgsetmap obj;

obj<<("tgset10","mystring");

obj.tgsetlist.size();
}

これにより、コンパイル エラーがスローされます。

"test.cc"、10 行目: エラー: tgsetmap::operator<<(const char , const char*) の引数の数が不正です。"test.cc"、22 行目: エラー: 操作 "tgsetmap << const char*" は不正です。2 エラーが検出されました。*

私はどこか間違っていますか?

4

4 に答える 4

4

operator<<右側に 2 つの引数を強制することはできません。次のコード:

obj<<("tgset10","mystring");

2 つの引数を持つ関数呼び出しとして機能せず、代わりに,演算子を使用します。しかし、それはおそらくあなたが興味を持っているものではありません.

2 つの引数を<<演算子に渡す必要がある場合は、それらを他の (単一の) 型でラップする必要があります。たとえば、標準のstd::pair、つまりstd::pair<const char*, const char*>.

ただし、は連鎖operator<<に適した合理的な型も返す必要があることに注意してください。<<それはおそらくtgsetmap&あなたの場合です。次のバージョンは正常に動作するはずです。

#include <map>
#include <string>
#include <iostream>

class tgsetmap
{
public:
    typedef std::map<std::string, std::string> list_type;
    typedef list_type::value_type item_type;

    list_type tgsetlist;

    tgsetmap& operator<<(item_type item)
    {
        tgsetlist.insert(item);
        return *this;
    }
};

int main()
{
    tgsetmap obj;

    obj << tgsetmap::item_type("tgset10","mystring")
        << tgsetmap::item_type("tgset20","anotherstring");

    std::cout << obj.tgsetlist.size() << std::endl;
}

型名を何度も繰り返す必要がないように、typedef を追加したことに注意してください。また、連鎖できるようにreturn operator<<aも作成しました(上記の変更のように使用されます)。最後に、簡単にするために を再利用しましたが、独自の他のタイプを使用することもできます。tgsetmap&<<main()std::map<...>::value_type


ただし、代わりに通常の方法を使用することをお勧めします。何かのようなもの:

void add(const char *str1, const char *str2)
{
    tgsetlist.insert( std::map<std::string, std::string>::value_type(str1, str2));
}

(クラス宣言内)、次に:

obj.add("tgset10", "mystring");
于 2012-07-18T07:16:22.733 に答える
1

クラスのoperator<<内部は、次のようにオーバーロードする必要があります。

T T::operator <<(const T& b) const;

2 つの引数でオーバーロードする場合は、クラスの外で行うことができます。

T operator <<(const T& a, const T& b);

たとえば、私のコンパイラは、投稿したコードに対してより詳細なエラー メッセージを表示します。 ここに画像の説明を入力

演算子のオーバーロード構文についてよくわからない場合は、それに関するwiki 記事があります。

于 2012-07-18T07:04:34.617 に答える
0

はい。operator << は二項演算子です。三元ではありません。このポインターを忘れないでください。

于 2012-07-18T07:04:08.570 に答える
0

前述のように、<<is 二項演算子であるため、2 つ以上の引数を取ることはできません (クラス内で宣言している場合は 1 つ、クラス外で宣言している場合は LHS にする必要があります)。ただし、 を実行することで同じ機能を実現できますobj<<"tgset10". <<"mystring";。しかし、<<は二項演算子であるため、これにはいくつかのハックを行う必要があります。

このために、静的変数op_countを割り当てました。ここで、それが値か型かを判断します。temp_strそして、呼び出し全体で以前の値を格納するための別の静的変数。

class tgsetmap
{
    public:
    std::map<std::string,std::string> tgsetlist;

    static int op_count = 0;
    static const char *temp_str;
    tgsetmap& operator<<(const char *str)
    {
        op_count++;
        if (op_count%2 != 0) {
            temp_str = str;
        }
        else {
            tgsetlist.insert( std::map<std::string,std::string>::value_type(temp_str,str));
        }
        return this;
    }
};

だからあなたはすることができます

int main()
{
    tgsetmap obj;
    obj<<"tgset10"<<"mystring";
    obj.tgsetlist.size();
}

または、単純に、区切り記号を使用して値とタイプを同じ文字列に埋め込むことができます。

値: タイプ = 区切り文字:

value_type = セパレータは _ です。

于 2012-07-18T08:07:31.967 に答える