I am trying to do an old project of my school, which deals with metaprogramming in C++98. The part I'm struggling against is about SFINAE.
The subject says I'm supposed to check if operator<<
works between a stream object and another object by the use of a struct like this :
template<typename Stream, typename Object>
struct IsPrintable;
It says I should write a weird line with "two null references", I guess it should look like this :
sizeof(*(static_cast<Stream *>(NULL)) << *(static_cast<Object *>(NULL)))
It works when the operator is supported, but doesn't compile when it isn't. I can't figure out where I fail, here is the file :
template<typename Flux, typename Object>
struct IsPrintable
{
typedef char yes[1];
typedef char no[2];
template<size_t N>
struct Test
{
typedef size_t type;
};
template<typename U>
static yes &isPrintable(U * = 0);
template<typename>
static no &isPrintable(...);
static const bool value = sizeof(isPrintable<Test<sizeof(*(static_cast<Flux *>(NULL)) << *(static_cast<Object *>(NULL)))> >(0)) == sizeof(yes);
};
The subject says explicitly to use a class taking a size_t as a parameter, and that the isPrintable method should take a NULL pointer to this class instance. Plus, the ugly expressions with static_cast should be used for a type definition, I tried to typedef it but the compiler screamed at me.
I don't get everything since I'm very new to this, I know there is some way to simplify that with the decltype
operator, but the aim of the project is to do it in C++98, and it could be useful if I find some code of that type later on.
#include <cstddef>
template<typename Flux, typename Object>
struct IsPrintable
{
typedef char yes[1];
typedef char no[2];
template <std::size_t N>
struct SFINAE {};
template <typename F, typename O>
static yes& isPrintable(SFINAE<sizeof( *static_cast<F*>(NULL) << *static_cast<O*>(NULL) )>* = 0);
template <typename F, typename O>
static no& isPrintable(...);
static const bool value = sizeof(isPrintable<Flux, Object>(NULL)) == sizeof(yes);
};
DEMO
template <typename Flux, typename Object>
struct IsPrintable
{
private:
typedef char yes[1];
typedef char no[2];
template <size_t N> struct Test
{
typedef size_t type;
};
template <typename U>
static yes& isPrintable(Test<sizeof(*(static_cast<Flux*>(NULL)) << *(static_cast<U*>(NULL)))>* = 0);
template <typename> static no& isPrintable(...);
public:
static const bool value = sizeof(isPrintable<Object>(0)) == sizeof(yes);
};
Live example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With