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<<在右侧接受两个参数。以下代码:

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

不能用作带有两个参数的函数调用,而是仅使用,运算符。但这可能不是你感兴趣的。

如果您需要将两个参数传递给<<运算符,则需要将它们包装在其他(单一)类型中。例如,您可以使用标准的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 以不必一遍又一遍地重复类型名称。我还做了operator<<return atgsetmap&以便<<可以链接(如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

是的。运算符 << 是二元运算符。不是三元的。不要忘记这个指针。

于 2012-07-18T07:04:08.570 回答
0

如前所述,<<is 二元运算符,因此它不可能占用两个以上的参数(如果您在类内声明,则应该是 this,如果在类外声明,则应该是 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 回答