Re: Determine if operator<< is implemented for a class
Am 29.03.2011 01:30, schrieb dec4106:
Part of the functionality we'd like to have for a logging class would
be to write out the value of an object passed in. Something like:
template<typename T>
void MyLog::writeError(string msg, T obj)
{
outputStream<< msg<< obj;
}
This won't compile if operator<< isn't defined for T. Is there a way
to have the compiler determine whether or not operator<< is defined
for a class, and if not call a different function?
Your requirements for your traits type are not entirely clear to me,
because you don't define what you consider as a stream. Assuming you
mean some specific specialization of std::basic_ostream<>, you might
want to try the following variant (You don't describe whether you need
the code in an C++03 environment or whether C++0x code would be fine as
well, therefore I assumed the former):
//------------------------------
#include <iosfwd>
namespace lib {
namespace details {
typedef char(&one)[1];
typedef char(&two)[2];
template<class T>
T& lval();
struct shim{ shim(...); };
struct no_match{};
// Only declared, never defined:
template<class CharT, class TraitsT>
no_match operator<<(std::basic_ostream<CharT, TraitsT>&, shim);
template <class T, class CharT = char,
class TraitsT = std::char_traits<CharT> >
struct has_io_inserter_impl {
private:
static one test(std::basic_ostream<CharT, TraitsT>&);
static two test(const no_match&);
public:
static const bool value = sizeof(
test(lval<std::basic_ostream<CharT, TraitsT> >() << lval<T>())
) == 1;
};
} // details
template <class T, class CharT = char,
class TraitsT = std::char_traits<CharT> >
struct has_io_inserter : details::has_io_inserter_impl<T, CharT,
TraitsT> {};
} // lib
struct No {};
struct Yes {};
std::ostream& operator<<(std::ostream&, Yes);
typedef bool check1[!lib::has_io_inserter<No>::value ? 1 : -1];
typedef bool check2[lib::has_io_inserter<Yes>::value ? 1 : -1];
int main()
{
}
//------------------------------
In regard to the second part of your question, it should be easy to use
boost::enable_if or std::enable_if (for a C++0x compiler) to
sfinae-dispatch between two implementations.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]