Reputation: 11677
I think I've been staring at this for too long or something, but I can't find my error here:
struct
{
bool empty() const
{
return true;
}
} hasEmpty;
template<typename T>
struct has_empty
{
private:
template<typename U, U>
class check {};
template<typename C>
static char f(check<void (C::*)() const, &C::empty> *);
template<typename C>
static long f(...);
public:
static const bool value = (sizeof(f<T>(nullptr)) == sizeof(char));
};
template<typename T>
typename std::enable_if<has_empty<T>::value>::type foo(const T& t)
{
}
void x()
{
foo(hasEmpty);
}
Visual Studio 2012 reports:
error C2893: Failed to specialize function template 'std::enable_if<has_empty<T>::value>::type foo(const T &)'
1> With the following template arguments:
1> '<unnamed-type-hasEmpty>'
(Note, I really like the new C++11 version of this test as described here, but VS2012 doesn't support constexpr, yet.)
Upvotes: 3
Views: 774
Reputation: 21900
Your hasEmpty::empty
method returns bool
:
struct
{
bool empty() const
{
return true;
}
} hasEmpty;
But your trait uses a member function pointer that returns void
, that substitution will always fail. You should change this:
template<typename C>
ctatic char f(check<void (C::*)() const, &C::empty> *);
For this:
template<typename C>
static char f(check<bool (C::*)() const, &C::empty> *);
That compiles for me.
Upvotes: 3