Search code examples
c++solaris

C++ ostream_withassign with << operator compile error


I'm working on some legacy code with an old Solaris compiler on Solaris 10 (no new fangled C++0x here ;-)

-bash-3.2$ CC -V

CC: Sun C++ 5.12 SunOS_sparc 2011/11/16

I've got a 3rd party dictionary class with an iterator

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()();
    ...
};

My code is supposed to go through each item in the dictionary but has a compile error that I can't explain:

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

Fails with "filename.cc", line 42: Error: The operation "ostream_withassign<<Key" is illegal.

But this version works:

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

Obviously I've got a workaround but I thought that since DictIterator.key() returns a K (not a reference), the two snippets were pretty similar. Can anyone let me know what weird corner of C++ I've just bumped into?

edit: To answer comments, << is overridden ostream& operator(ostream &, Key&);


Solution

  • The operator<< takes its right argument by non-const lvalue reference. This means that temporaries cannot be bound to this argument.

    The key() method returns a temporary. Only by creating a local variable can you turn this temporary into a variable that the lvalue reference can bind to.

    Changing the argument of the operator to a const Key& solves this problem because a const lvalue reference can bind to temporaries. This should be a minimally invasive and safe change - it could only fail to work if the output operator used non-const functionality of the object being written, which would be a big red flag in itself. However, if the existing code is not const-correct (i.e. member functions that do not modify their objects are not consistently marked as const), this may lead to a long tail of fixing such const-correctness violations.