简体   繁体   中英

How to initialize custom analogue for std::cout?

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 .

How can I create a direct analogue of std::cout that could be used for my strings and use std::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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM