Reputation: 251
I am trying to develop a simple logger.
I have a function with the following prototype:
class Logger{
public:
std::unique_ptr<MyStream> & getLogger(string, string);
}
and i want to do something like
logger = Logger();
logger.log("INF", "HGH") << "My message" << endl;
for this i overloaded the operator<<
template<typename T>
inline friend std::unique_ptr<MyStream> &operator<<(std::unique_ptr<MyStream>&os, const T&val){
*os << val;
return os;
}
inline friend std::unique_ptr<MyStream>& operator<<(std::unique_ptr<MyStream>&os, std::ostream&(*f)(std::ostream&) ){
*os << f;
return os;
}
But when i try to do
auto infLogger = log.log(M_LOG_NRM, M_LOG_INF);
infLogger<< "Testing new functionality" << std::endl;
Everything works fine but when i do:
log.log("MOD1", M_LOG_NRM, M_LOG_INF) << "Testing new functionality" << std::endl;
I have this nice compilation error:
cannot convert ‘jpCppLibs::Logger::log(int, int)(std::basic_string<char>(((const char*)"MOD1"), (*(const std::allocator<char>*)(& std::allocator<char>()))), 3, 3)’ (type ‘std::unique_ptr<jpCppLibs::MyStream>’) to type ‘std::unique_ptr<jpCppLibs::MyStream>&’
log.log(M_LOG_NRM, M_LOG_INF) << "Testing new functionality" << std::endl;
Any help?
The class was working passing by parameter the message and the format+variables, just trying to improve it a little bit
Upvotes: 0
Views: 64
Reputation: 275385
template<typename T>
inline friend std::unique_ptr<MyStream> const&operator<<(std::unique_ptr<MyStream> const&os, const T&val){
*os << val;
return os;
}
note that a std::unique_ptr<MyStream> const&
and std::unique_ptr<MyStream const>&
are different types. The first is a reference to a immutable smart pointer to mutable data, the second is a reference to a mutable smart pointer to immutable data.
Temporary objects cannot bind to non-const
lvalue references, as protection against implicit conversions leading to changes being discarded silently. However, you do not need a non-const
lvalue reference, so there is no problem.
Upvotes: 1
Reputation: 153909
Because you're trying to initialize a non-const reference with a temporary, and that's not allowed.
The usual solution for this problem is to write a small class
(which may contain nothing more than your std::unique_ptr
),
with a template member operator<<
; the rules allow member
functions to be called on temporaries.
Upvotes: 1