开发者

ostream<<Iterator, C++

开发者 https://www.devze.com 2023-04-11 12:11 出处:网络
I\'m trying to build an operator which prints list, Why won\'t ostream<<*it compile? void operator<<(ostream& os, list<class T> &lst)

I'm trying to build an operator which prints list,

Why won't ostream<<*it compile?

void operator<<(ostream& os, list<class T> &lst)
{
     list<T>::iterator it;
     for(it = lst.begin(); it!=lst.end(); it++)
     {
                  os<<*it<<endl; //开发者_如何学JAVAThis row
     }
}


Because *it does not implement stream insertion. That is, there is no overload for operator<< that takes an ostream and a T. Note that you should be returning the ostream& os to allow operator chaining. Also your function template definition looks wrong. Consider doing this instead:

template< typename T >
ostream& operator<<(ostream& os, list<T> const& lst)
{
    std::copy(
        lst.begin(), lst.end()
      , std::ostream_iterator< T >( os )
    );
    return os;
}

or better yet, to support streams over all kind of elements and traits:

template< typename Elem, typename Traits, typename T >
std::basic_ostream< Elem, Traits >& operator<<(
    std::basic_ostream< Elem, Traits >& os
  , std::list<T> const& lst
)
{
    std::copy(
        lst.begin(), lst.end()
      , std::ostream_iterator< T >( os )
    );
    return os;
}

Adittionaly, you can pass a separator to std::ostream_iterator constructor to be inserted between each element.

* Update: * I just noticed that even if your function template declaration were correct, you would be dealing with a dependent type. The iterator is dependent on the type T, so you need to tell this to the compiler:

typename list<T>::iterator it;


I think the problem is in your template declaration. The following should compile and work just fine:

template <typename T>
void operator<<(ostream& os, list<typename T> &lst)
{
      list<T>::iterator it;
      for(it = lst.begin(); it!=lst.end(); it++)
      {
                  os<<*it<<endl;
      }
}

This is provided of course that the element type of your list can actually be used with the << operator of an ostream.


You are using template syntax the wrong way:

template<class T>
void operator<<(ostream& os, list<T> &lst)
{
    list<T>::iterator it;
    for(it = lst.begin(); it!=lst.end(); it++)
    {
        os<<*it<<endl; //This row
    }
}

And by the way, you should return a reference to the stream to allow chaining of output operators, and the list should be const, and you can also use the standard library for doing the output loop:

template<class T>
std::ostream& operator<<(std::ostream& os, const std::list<T> &lst)
{
    std::copy(lst.begin(), lst.end(), std::ostream_iterator<T>(os, "\n"));
    return os;
}


Rewrite to:

template<class T>
ostream& operator<<(ostream& os, list<T>& lst){
    typename list<T>::iterator it;
    for(it = lst.begin(); it != lst.end(); ++it){
                 os << *it << endl;
    }
    return os;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号