Search code examples
c++templatesoperator-overloadingcompile-timestream-operators

Making multiple operator<<() definition for a single class


So basically this is what I want to make:

void someMethod() {
    StreamClass streamClass{};

    streamClass << "Something" << "\n"; //do something
    streamClass.doA << "Something" << "\n"; //do another thing
    streamClass.doB << "Something" << "\n"; //do something else

    //If the first one is impossible, what about this?
    streamClass << "Something" << "\n"; //do something
    streamClass::doA << "Something" << "\n"; //do another thing
    streamClass::doB << "Something" << "\n"; //do something else

    //Or this?
    streamClass<enumA> << "Something" << "\n"; //do something
    streamClass<enumB> << "Something" << "\n"; //do another thing
    streamClass<enumC> << "Something" << "\n"; //do something else
}

Header file:

class StreamClass {
public:
    StreamClass(); //Init class
    //... and many other things
    template<typename T>
    StreamClass& operator<<(T t) {
        //... do something that uses data and t
    }
    //And do something here?
protected:
    Data data; //some data owned by this object
};

So, is there anyway to do something like that? And how to do it in the fastest way?


Solution

  • The first way is perfectly viable, as long as you make doA and doB members of StreamClass, give them a reference to the StreamClass instance that has them (during construction) and make them implement operator<<.

    At the end, the types of doA and doB should hold a reference/pointer to StreamClass or StreamClass::Data. Consider forbidding copy/move constructors and assignment operators.


    The second option is syntactically valid, but requires doA and doB to be static, which ultimately makes it impossible to have two StreamClass instances at the same time with different behavior.

    The last way is syntactically invalid, given that streamClass is not a variable template.