Убедитесь, что производный класс реализует статический метод

Я хочу убедиться, что производный класс реализует определенный статический метод. Я думаю, что это должно быть возможно с помощьюstatic_assert, станд :: is_same, decltype, CRTP и, возможно, используяSFINAE, Тем не мение,аналогичный код Я обнаружил, что пока что это довольно сложно, и, кажется, я еще не до конца понимаю, что делает меня неспособным приспособить его к своим потребностям.

То, что я пробовал до сих пор, это

template <class T>
class Base 
{
    static_assert(std::is_same<decltype(T::foo(1)), int>::value, "ERROR STRING");
};

class Derived : public Base <Derived>
{
public:
    static int foo(int i) { return 42; };
};

Тем не менее, он не компилирует, сообщая мне, что Derived не имеет элемента с именем foo, даже если метод реализован правильно. Кроме того, предоставление фактических параметров для foo в выражении в static_assert кажется неправильным.

Поиск SO выявил аналогичный вопрос, который в конечном итоге привело меня кэтот кусок кода где проверяется, что тип имеет методы begin () и end (), возвращающие итераторы. Поэтому я попытался принять этот код для своих нужд.

template <class T>
class Base 
{
    template<typename C>
    static char(&g(typename std::enable_if<std::is_same<decltype(static_cast<int(C::*)(int)>(&C::foo)), int(C::*)(int)>::value, void>::type*))[1];

    template<typename C>
    static char(&g(...))[2];

    static_assert(sizeof(g<T>(0)) == 1, "ERROR STRING");
};

Но этот код не компилируется, потому что утверждение срабатывает.

Так что мои вопросы

Почему компилятор не может найти Derived :: foo в моем первом примере?Что именно делаетtypename C::const_iterator(C::*)() const в примере кода имеется ввиду? Разве это не константная функция, возвращающая C :: const_iterator и не принимающая аргументов? Что именно делаетC::* имею в виду? Так почему жеint(C::*)(int) тогда неправильно в моем случае?Как правильно решить мою проблему?

Я использую MSVC 12, но, если возможно, код должен быть переносимым.

Ответы на вопрос(1)

Ваш ответ на вопрос