代码之家  ›  专栏  ›  技术社区  ›  John3136

C++ostream\u with assign with<<运算符编译错误

  •  1
  • John3136  · 技术社区  · 6 年前

    我正在使用Solaris 10上的旧Solaris编译器编写一些遗留代码(这里没有新的C++0x;-)

    -bash-3.2美元CC-V

    抄送:Sun C++5.12 SunOS\u sparc 2011/11/16

    我有一个带迭代器的第三方字典类

    template<K, V>
    class DictIterator
    {
        public:
            DictIterator(TheDictClass<K, V>& collection);
            K key() const;
            V value() const;
            // advance the iterator. return true if iterator points to a valid item
            bool operator()();
        ...
    };
    

    我的代码应该遍历字典中的每一项,但有一个编译错误,我无法解释:

    DictIterator iterator(theDictionary);
    while(iterator())
    {
        cout << iterator.key(); 
    }
    

    故障原因 "filename.cc", line 42: Error: The operation "ostream_withassign<<Key" is illegal.

    但这个版本有效:

    DictIterator iterator(theDictionary);
    while(iterator())
    {
        Key key(iterator.key());
        cout << key; 
    }
    

    显然我有一个解决办法,但我想 DictIterator.key() 返回a K (不是参考),这两个片段非常相似。有没有人能告诉我,我刚刚碰到了C++的哪个奇怪的角落?

    编辑:回答评论, << 被覆盖 ostream& operator(ostream &, Key&);

    1 回复  |  直到 6 年前
        1
  •  3
  •   Sebastian Redl    6 年前

    这个 operator<< 通过非常量左值引用获取其右参数。这意味着临时变量不能绑定到此参数。

    这个 key() 方法返回临时。只有创建一个局部变量,才能将这个临时变量转换为左值引用可以绑定的变量。

    将运算符的参数更改为 const Key& 解决了这个问题,因为常量左值引用可以绑定到临时对象。这应该是一个微创且安全的更改-只有当输出操作符使用正在写入的对象的非常量功能时,它才可能失败,这本身就是一个巨大的危险信号。但是,如果现有代码不正确(即,不修改其对象的成员函数不一致地标记为 const ),这可能会导致修复此类常量正确性冲突的长尾。