H-005
H-005

Reputation: 505

How to overload the << operator so it only affects a member of a class?

I have a class Bitset that stores a vector of chars, and I want to be able, whenever I use cout << char, to cast that char into a short int ONLY if it is part of that class.

Code:

template<long long X>
class Bitset
{
    public: std::vector<unsigned char> bit = std::vector<unsigned char> ((X+7)/8);

    public:
        /* constructors */

        friend std::ostream &operator<< (std::ostream &output, const char x);
};

std::ostream &operator<< (std::ostream &output, const char x)
{
    output<<(short)(x);
    return output;
}

The idea is that if I write:

Bitset a;
/* code */
cout << a.bit[x];
cout << 'a';

I want to cast a.bit[x] into a short, but not 'a' as well.

Upvotes: 1

Views: 290

Answers (2)

catnip
catnip

Reputation: 25388

I would adopt a very simple approach to this: just implement a function in your class with the following signature:

short GetElementAsShort (size_t index);

And then you can of course do:

Bitset <128> a;
std::cout << a.GetElementAsShort (42) << "\n";

I really don't see why anything more complicated as needed. It also makes it obvious what's going on when you read the code.

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 595305

You can't overload operator<< for char to behave the way you want. It has no idea where the char comes from, so it can't behave differently based on the source.

To make this work the way you want, you will have to make Bitset implement its own operator[] that returns a proxy object, and then you can overload operator<< for that proxy, eg:

template<long long X>
class Bitset
{
private:
    std::vector<unsigned char> bits = std::vector<unsigned char> ((X+7)/8);

public:
    /* constructors */

    class BitProxy
    {
    private:
        unsigned char &bit;

    public:
        BitProxy(unsigned char &bit) : bit(bit) {}

        BitProxy& operator=(unsigned char x) { bit = x; return *this; }
        operator unsigned char() const { return bit; }
    };

    BitProxy operator[](size_t index) { return BitProxy(bits[index]); }

    friend std::ostream& operator<< (std::ostream &output, const BitProxy &x)
    {
        output << static_cast<short>(static_cast<unsigned char>(x));
        return output;
    }
};
Bitset a;
// populate a as needed...
cout << a[x];
cout << 'a';

Live Demo

Upvotes: 7

Related Questions