Reputation: 79
I am trying to implement my own basic_string
, but came across a problem with printing my strings. I am not going to use std::char_traits
and other traits from std, as I've implemented ones myself. How can I create a direct analogue of std::cout
that could be used for my strings and use std::basic_ostream
for that? (not gonna create basic_ostream
myself).
I tried some approaches to the problem. I created the following operator:
template<typename CharType, typename CharTraits>
std::basic_ostream<CharType, CharTraits>&
operator<<(std::basic_ostream<CharType, CharTraits>& o, const AnyString<CharType, CharTraits>& str)
{
using size_type = AnyString<CharType, CharTraits>::size_type;
for (size_type i = 0u; i < str.size(); ++i)
{
o << str[i];
}
return o;
}
Then I tried using it with std::cout
like this:
cout << str;
but the problem was: "no operator<< matches these operands".
The reason is std::cout uses std::char_traits<char>
but not CharTraits<char, int>
that I developed.
I decided to create my own version of std::cout
:
using Ostream = std::basic_ostream<char, CharTraits<char, int> >;
Ostream Cout;
But it doesn't compile for this reason:
std::basic_ostream<char,CharTraits<char,int>>': no appropriate default constructor available
I need to understand what is the most appropriate way to initialize my version of std::cout
.
Upvotes: -2
Views: 102
Reputation: 598134
How can I create a direct analogue of
std::cout
that could be used for my strings and usestd::basic_ostream
for that?
You don't need to create a custom ostream
at all. All you need is an overload of operator<<
for the standard std::ostream
, eg:
template<typename CharType, typename CharTraits>
std::ostream& operator<<(std::ostream& o, const AnyString<CharType, CharTraits>& str)
{
// print the contents of str to out as needed...
using size_type = AnyString<CharType, CharTraits>::size_type;
for (size_type i = 0u; i < str.size(); ++i)
{
o << (char) str[i];
}
return o;
}
Or, if you want the ostream
to match the CharType
of your string (ie, using std::cout
for char
strings, std::wcout
for wchar_t
strings, etc), you can use this instead:
template<typename CharType, typename CharTraits>
std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& o, const AnyString<CharType, CharTraits>& str)
{
// print the contents of str to out as needed...
using size_type = AnyString<CharType, CharTraits>::size_type;
for (size_type i = 0u; i < str.size(); ++i)
{
o << str[i];
}
return o;
}
For example, the following code: ... doesn't compile for this reason:
That is because you are trying to create a default-constructed instance of std::basic_ostream
, which doesn't have a default constructor. That has nothing to do with your custom string class.
Upvotes: 5