Feb 3, 2021 at 4:50pm UTC
I have a class I am working on which let's me use the << operator on various types. I have defined the operator for integral types and for strings. I would like the definition for strings to only apply to literal strings and not pointers to strings. For example:
LOGSTREAM() << "Oh my!!"; // OK
std::string foo;
LOGSTREAM() << foo.c_str(); // NOPE
But I can't seem to find a way to code this.
Thanks!!!
-Jim.
class LOGSTREAM {
. . .
enum class enabler_t { };
template<typename T>
using EnableIf = typename std::enable_if<T::value, enabler_t>::type;
template<class T, EnableIf<std::is_integral<T>>...>
LOGSTREAM& operator <<(T arg) {
. . .
return *this;
}
template <class T, EnableIf<std::is_same<const char*, T>>...>
LOGSTREAM& operator <<(T arg) {
. . .
return *this;
}
. . .
};
Feb 3, 2021 at 5:10pm UTC
> "Oh my!!"
that's a const char *
> foo.c_str()
that's also a const char *
there is no «literal» modifier, you can't distinguish them.
¿why do you want to make your interface so awful?
Feb 3, 2021 at 5:10pm UTC
Overload, don't specialise:
http://www.gotw.ca/publications/mill17.htm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#include <iostream>
#include <type_traits>
struct logstm
{
logstm( std::ostream& stm ) : stm(stm) {}
template < typename T >
typename std::enable_if< std::is_integral<T>::value, logstm& >::type // ovrload for integral types
operator << ( const T& v ) { stm << v << ' ' ; return *this ; }
template < std::size_t N > // overload for literal strings (narrow)
logstm& operator << ( const char (&literal_string)[N] ) { stm << '"' << literal_string << "\" " ; return *this ; }
std::ostream& stm ;
};
int main()
{
logstm lg(std::cout) ;
lg << 1234 << "hello world!" << '\n' ;
}
http://coliru.stacked-crooked.com/a/b5c88ffe2e30eae6
The overload for literal strings is really one for 'array of const char'
Last edited on Feb 3, 2021 at 5:15pm UTC
Feb 3, 2021 at 7:29pm UTC
Ok, followup:
Let's say in addition to supporting literal strings I also want to support non-literal string in a separate operator<< definition.
Edit:
Nevermind I think have it with:
// overload for integral types
template < typename T >
typename std::enable_if< std::is_integral<T>::value, LOGSTREAM& >::type
operator << ( const T& arg ) {
elems_.push_back(arg);
return *this;
}
// overload for literal strings (narrow)
template < std::size_t N >
LOGSTREAM& operator << ( const char (&arg)[N] ) {
elems_.push_back(arg);
return *this;
}
// for non-literal strings
template < typename T >
typename std::enable_if< std::is_same<const char*, T>::value, LOGSTREAM& >::type
operator << ( T arg ) {
elems_.push_back(LOGELEM(LOGTYPE::STR, arg));
return *this;
}
Last edited on Feb 3, 2021 at 7:51pm UTC