I need to check if a given class has the <<(cls, ostream)
operator defined or not. If so, I want my function to use that to write to ostringstream
, otherwise boilerplate code should be used.
I know this question has been asked before. However, I generally find custom solutions that don't always work on my compiler (clang++). After many hours of searching, I finally found out that boost::type_traits. I hadn't look there previously, because I had assumed c++11 already copied everything in the traits department that boost had.
The solution that worked for me was to do:
template <typename C>
std::string toString(C &instance) {
std::ostringstream out;
out << to_string<C, boost::has_left_shift<C, std::ostream>::value>::convert(ctx);
return out.str();
}
with to_string
defined as:
template <typename C, bool>
struct to_string {
// will never get called
static std::string convert(LuaContext &ctx) {}
};
template <typename C>
struct to_string<C, true> {
static std::string convert(LuaContext &ctx) {
return "convert(true) called.";
}
};
template <typename C>
struct to_string<C, false> {
static std::string convert(LuaContext &ctx) {
return "convert(false) called.";
}
};
So I'm posting this for two reasons:
Check if this is the sanest method to use, or see if someone else can suggest an even better solution (i.e. the question is more out of curiosity of approach than "will this work?" -- it already works for me)
Post this up to save someone else hours of searching in case she/he also needs to do something similar.
As a more general question -- sometimes trait classes appear to return std::true_type or std::false_type (well, at least for non-boost classes). Other times they are bools. Is there a reason for this discrepancy? If
boost:has_left_shift
returned a type instead of abool
, then I could have just a singleto_string
struct.