[cfe-dev] [libcxx] <iterator> header dependencies

Mikhail Maltsev via cfe-dev cfe-dev at lists.llvm.org
Fri Nov 24 07:22:18 PST 2017

Hi, all.

I noticed several issues with missing header dependencies. Specifically the following code compiles with libstdc++ but not libc++:

$ cat istream-1.cc
#include <iterator>
typedef std::istreambuf_iterator<char> iter;

bool foo(const iter& a, const iter& b)
    return a == b;

$ clang++ -stdlib=libc++ istream-1.cc
In file included from istream-1.cc:1:
/opt/data/llvm/install/bin/../include/c++/v1/iterator:948:32: error: implicit instantiation of undefined template 'std::__1::char_traits<char>'
                      typename _Traits::off_type, _CharT*,
istream-1.cc:6:14: note: in instantiation of template class 'std::__1::istreambuf_iterator<char, std::__1::char_traits<char> >' requested here
    return a == b;
/opt/data/llvm/install/bin/../include/c++/v1/iosfwd:100:53: note: template is declared here
template<class _CharT>  struct _LIBCPP_TEMPLATE_VIS char_traits;


I.e., the definition of char_traits is missing. It can be fixed by including the <__string> header, but then it would fail due to missing std::basic_streambuf. Including <streambuf> will make the code compile.

Two more issues:

$ cat iostream-iter.cc
#include <iterator>
typedef std::istream_iterator<char, char> istream_iter;
typedef std::ostream_iterator<char, char> ostream_iter;

void foo(istream_iter::istream_type& stream)
    istream_iter iter(stream);

void bar(ostream_iter::ostream_type) { }

$ clang++ -stdlib=libc++ iostream-iter.cc
iostream-iter.cc:10:36: error: implicit instantiation of undefined template 'std::__1::basic_ostream<char, std::__1::char_traits<char> >'
void bar(ostream_iter::ostream_type) { }
/opt/data/llvm/install/bin/../include/c++/v1/iosfwd:111:32: note: template is declared here
    class _LIBCPP_TEMPLATE_VIS basic_ostream;
In file included from iostream-iter.cc:1:
/opt/data/llvm/install/bin/../include/c++/v1/iterator:892:33: error: invalid operands to binary expression ('std::__1::istream_iterator<char, char, std::__1::char_traits<char>, long>::istream_type'
      (aka 'basic_istream<char, std::__1::char_traits<char> >') and 'int')
            if (!(*__in_stream_ >> __value_))
                  ~~~~~~~~~~~~~ ^  ~~~~~~~~
iostream-iter.cc:7:18: note: in instantiation of member function 'std::__1::istream_iterator<char, char, std::__1::char_traits<char>, long>::istream_iterator' requested here
    istream_iter iter(stream);
2 errors generated.

Here foo requires the definitions of basic_istream::operator>> (for fundamental types) to be available, and bar requires basic_ostream copy c-tor (note that the stream is passed by value). These errors can be fixed by including <istream> and <ostream> respectively.

My question is: should these headers be included into <iterator> or am I missing some wording in the C++ standard, that requires the user to include them?


   Mikhail Maltsev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20171124/dab35023/attachment-0001.html>

More information about the cfe-dev mailing list