I have a class for logging, which MUST NOT inherit std::ostream, and has operator<< defined for the same types as the standard output stream PLUS a templated version:
class MyLoggingClass {
[...]
public:
template<typename T> MyLoggingClass & operator<<( T& data ){ ... }
}
Also, for every printable class in my program, I have the typical non-member function defined:
std::ostream & operator << ( std::ostream & os, const OneOfMyClasses & foo );
The thing is that, internally, my logger sometimes uses an standard output stream, this is:
template<typename T>
MyLoggingClass & operator<<( T& data )
{
[...]
if( someCondition )
{
cout << data;
}
[...]
}
Thanks to this, I can log my classes without explicitly replicating on every of them the non-member operator<< for MyLoggingClass.
The problem comes in a line where I try to log an object created “on the fly”:
MyLoggingClass logger;
logger << OneOfMyClasses(params); // Here I am invoking the constructor of class "OneOfMyClasses"
The thing is that, instead of invoking the constructor, and then passing the object as parameter of the operator<<, it interprets that I’m trying to log a pointer to function.
Of course, some valid solutions for this problem include:
- Removing the templated operator<<, and making MyLoggingClass extend std::ostream
- Removing the templated operator<<, and creating tons of non-member operator<<( MyLoggingClass &, const OneOfMyClasses & )
- Storing the object to log in a temporal variable, and then doing “logger << temporalObject;”
However, I would like to know if there is a way to force the compiler evaluating the constructor call. Do you know any workaround for this case?
Thank you in advance for your time 🙂
I think this is the problem is:
datais non-const reference and the line:is attempting to bind a temporary to a non-const reference.
Change to: