I would like the following code to compile when foo gets anything derived from base, otherwise a compile error ensues. I have written the type-trait class is_Base because the std::is_base_of
does not work well with my template stuff. I am close. I got it to work using a static_passoff
thing, but I would like to not have to use it. So how can write the enable_if without the static_passoff
hack? Here is the running version: http://coliru.stacked-crooked.com/a/6de5171b6d3e12ff
#include <iostream>
#include <memory>
using namespace std;
template < typename D >
class Base
{
public:
typedef D EType;
};
template<class T>
struct is_Base
{
using base_type = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
template<class U>
static constexpr std::true_type test(Base<U> *) { return std::true_type(); }
static constexpr std::false_type test(...) { return std::false_type(); }
using value = decltype( test((T*)0) );
};
template < typename A >
using static_passoff = std::integral_constant< bool, A::value >;
template <typename T, typename = typename std::enable_if< static_passoff< typename is_Base< T >::value >::value >::type >
void foo(T const&)
{
}
class Derived : public Base<Derived> {};
class NotDerived {};
int main()
{
Derived d;
//NotDerived nd;
foo(d);
//foo(nd); // <-- Should cause compile error
return 0;
}
I'm not entirely sure I understand your question given that your code does work. But stylistically, for metafunctions that yield a type, that type should be named
type
. So you should have:Or, to avoid the zero-pointer-cast-hack:
Also, your
test
doesn't need a definition. Just the declaration. We're not actually calling it, just checking its return type. It doesn't have to beconstexpr
either, so this suffices:Once you have that, you can alias it:
And use the alias: