2012-07-18 151 views
1

这下面的程序我已经写了一些测试。运算符重载C++(<<)

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

我错了吗?

回答

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; 
} 

请注意,我添加类型定义,不必一遍遍重复类型名称。我也让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"); 
+0

我确实知道这一点,但我想在这里使用流操作符。对我来说不是那么有趣的解决方案。 – Vijay 2012-07-18 09:23:05

+0

前段时间我还添加了'<<'运算符代码。 – 2012-07-18 09:26:57

+0

谢谢Michal.Learned一个新的东西:) – Vijay 2012-07-19 06:12:59

0

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

1

operator<<一个类的内部必须重载这样的:

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

如果你想以2个参数重载它,你可以做一个类的外:

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

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

如果您不是确定一个操作符重载语法,关于它有一个wiki article

+0

需要清除这些知识,请在相同问题或任何C++好书中加入链接 – gaussblurinc 2012-07-18 07:06:45

+0

在这里您可以找到一本书:http://stackoverflow.com/questions/388242/the-definitive-c-book-指导和列表 – 2012-07-18 07:26:27

+0

在这两种情况下,<<将采取两个参数 - 'a << b' a是第一个,b是第二个。如果你已经在课堂上声明了,第一个参数就是隐含的。所以无论如何,你不能让运营商采取两个以上的参数。但是你可以做这个'a << b << c'。这是你想要的? – Mohan 2012-07-18 07:54:42

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 =分隔符是_。