运算符重载c ++(<<<

时间:2012-07-18 07:02:20

标签: c++ map operator-overloading

这是我编写的以下程序进行的一些测试。

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&lt;&lt;(const char ,const char *)的参数数量非法。 “test.cc”,第22行:错误:操作“tgsetmap&lt;&lt; const char *”是非法的。 2检测到错误。*

我错在哪里?

4 个答案:

答案 0 :(得分: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<<返回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");

答案 1 :(得分:1)

类中的operator<<必须像这样重载:

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

如果你想用2个参数重载它,你可以在类之外完成它:

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

例如,我的编译器为您发布的代码提供了更详细的错误消息: enter image description here

如果您不确定运算符重载语法,则有一个wiki article

答案 2 :(得分:0)

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

答案 3 :(得分:0)

如前所述,<<是二元运算符,所以它不可能超过两个args(如果你在类中声明,那么一个应该是这个;如果你在类外声明,则应该是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 = separator is:

value_type = separator是_。