错误:没有运算符“<<”与这些操作数匹配

Posted

技术标签:

【中文标题】错误:没有运算符“<<”与这些操作数匹配【英文标题】:Error : No operator “<<” matches these operands 【发布时间】:2014-02-19 05:01:41 【问题描述】:

我仍然对 c++ 相当生疏,我无法理解我的问题。我收到的错误消息是“没有运算符 '

for(int i = 0; i < ruleList.size(); i++)

    cout << ruleList[i].lhs << endl;
    cout << ruleList[i].rhs << endl; // Problem printing this


struct Rules

string lhs;
vector<string> rhs;
rule;

vector<Rules> ruleList;

这样做是否合适?我用同样的方法做了 lhs,效果很好。

rule.rhs.push_back(token);
ruleList.push_back(rule);

【问题讨论】:

无法直接使用cout 打印vector。循环遍历向量并逐个打印每个元素, 【参考方案1】:

没有为标准容器定义operator&lt;&lt;。您将需要编写一个打印函数,类似于:

void print(std::ostream& out, std::vector<std::string> const & data) 
   std::copy(data.begin(), data.end(),
             std::ostream_iterator<std::string>(out, " "));

然后将其用作:

print(std::cout, ruleList[i].rhs);

【讨论】:

非常有帮助!谢谢!【参考方案2】:

std::vector 没有定义operator &lt;&lt;。您可以使用std::ostream_iterator 来格式化列表:

std::copy( ruleList[i].rhs.begin(), ruleList[i].rhs.end(),
           std::ostream_iterator< std::string >( std::cout, ", " ) );

这有点不完美,", " 在最后一个元素之后打印,但可以解决。

【讨论】:

【参考方案3】:

您需要为struct rules 编写自己的&lt;&lt; 运算符。在 C++11 中应该是这样的:

struct rules 
    string lhs;
    std::vector<std::string> rhs;

    // apparently it's a good idea to keep this out of std:: namespace
    inline static std::ostream & operator << (std::ostream & out, const rules & r) 
        out << r.lhs << std::endl;
        //for (int i = 0; i < v.length(); i++)
        for (auto & s : r.rhs) 
            out << s;
        
        out << std::endl;
        return out;
    

MSDN 在这里写了一篇文章:http://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx

【讨论】:

不要,您不能在::std 之外正确重载运算符(ADL 找不到),并且您不能合法地在@987654327 内部提供重载@. 基于***文章 (en.wikipedia.org/wiki/Argument-dependent_name_lookup) 我不认为这是一个问题,除非你正在处理一个巨大的代码库,否则会有很多冲突的重载。 但是对于 C++ 中的 any 函数,可以提出完全相同的论点。 问题在于特定的功能是一个常见的。在代码所在的任何命名空间中都非常经常找到operator&lt;&lt;,在这种情况下,非限定查找将不会在外部命名空间中查找并且会失败。它与其他功能有什么不同?您最后一次看到接线员呼叫合格是什么时候? ::operator&lt;&lt;(std::cout, myvector)?考虑到在一般情况下,您甚至不知道那个或 std::cout.operator&lt;&lt;(object) 是否是正确的语法...运算符是 ADL 的原因。 考虑到在他的情况下 operator &lt;&lt; 还没有工作,这意味着 operator &lt;&lt; 没有已经定义,所以他应该可以这样做这种情况下无需担心名称冲突/阴影。我仍然不相信覆盖一般情况是不好的做法,但感谢您指出一些可能发生的问题。 你没有理解我的意思。重载运算符很好,但它必须在 right 命名空间中。除了 right 命名空间不能在此处使用,因为您不能将重载添加到 ::std 命名空间。问题不在于重载 operator,而是在 wrong 命名空间中这样做(假设 right 是非法的)。您将在哪个命名空间中定义它?全球的?现在考虑你有一个类型::A::T,它也有::A::operator&lt;&lt;(std::ostream&amp;,::A::T const&amp;),现在考虑一个嵌套在::A中的函数[…]

以上是关于错误:没有运算符“<<”与这些操作数匹配的主要内容,如果未能解决你的问题,请参考以下文章

对象向量 - C++。没有运算符“<<”与这些操作数匹配,错误

没有运算符 << 匹配这些操作数

错误 C2679:二进制“<<”:未找到采用“std::string”类型右侧操作数的运算符(或没有可接受的转换)

C++基础 为什么不能cout一个string

没有运算符“=”匹配这些操作数错误

错误:二进制“<<”:未找到采用“std::string”类型的右侧操作数的运算符 [重复]