I'd like to ensure some derived classes implement a static method and found this SO question: Ensure derived class implements static method The top answer uses CRTP to solve the issue with a static_assert
in the base class destructor to ensure that the template argument type implements a static int foo(int)
.
However, as noted by a comment on the answer "There is a slight issue with this answer: writing out a destructor has the consequence of disabling the generation of a move constructor and move assignment operator. It also prevents the object from being trivially_destructible. So, while it works, there are downsides to the approach (and such downsides apply to other special members)." – @Matthieu M
Is there a way to avoid this downside? I've tried moving the static_assert
to both a member function and static member function of Base
, but in both cases it doesn't produce a compile-time error when a derived class doesn't implement static int foo()
. Here's the code I've been working with (tweaked from the above SO thread):
#include <type_traits>
template <class T>
class Base {
public:
//~Base() //This works as expected! Compile error because Bad doesn't implement static int foo()
//{
// static_assert(std::is_same<decltype(T::foo()), int>::value, "ERROR: No 'static int foo()' member provided");
//}
static void static_test() //This does not work. No compile time error.
{
static_assert(std::is_same<decltype(T::foo()), int>::value, "ERROR: No 'static int foo()' member provided");
}
};
class Good : public Base<Good> {
public:
static int foo() { return 42; };
};
class Bad : public Base<Bad> {
public:
static double foo() { return 42; };
};
int main()
{
Good g;
Bad b;
}