I thought that's why you wrote "static_assert instead of trying to be SFINAE-friendly" then, but okay.
> I'm just curious about a use case you have where you use enable_if on completeness.
That's all you want, without SFINAE? How about something like this:
template<class T>
class S {
std::unique_ptr<unsigned char[]> buf;
public:
template<std::enable_if_t<((void)sizeof(T), true), bool> = false>
explicit S(unsigned char *p, size_t n) : buf(p) {
assert(sizeof(T) <= n);
}
// ...
};
NDEBUG optimizes out the completeness check that's implicit in the assert() call, but you'd still want to ensure completeness even without the assert, so you write it explicitly. Obviously you can use static_assert here too, but merely using enable_if in lieu of that doesn't suddenly get you an ODR violation.EDIT:
Come to think of it, actually I think static_assert here is less safe than enable_if and increases the risk of an ODR violation. Check out the difference in behavior here when you uncomment the enable_if_t:
#include <type_traits>
class X;
template<class T>
class S {
public:
// template<std::enable_if_t<((void)sizeof(T), true), bool> = false>
explicit S(unsigned char *) {
static_assert(sizeof(T) > 0, "oops");
}
};
static S<X> s(nullptr);
int main() { }
class X { };