jeudi 19 mars 2020

Check if templated member function exists SFINAE

Following issue: I want to check whether a templated method is existing or not, herefore I have adapted the examples given here: Is it possible to write a template to check for a function's existence?

#include <cstdio>
#include <type_traits>

#define CHECK4_MEMBER_FUNC(RETTYPE,FUNCTION,...) \
template <class ClassType> \
class CIfCheck_##FUNCTION \
{\
private: \
    template <class MemberPointerType> \
    static std::true_type testSignature(RETTYPE (MemberPointerType::*)(__VA_ARGS__)); \
\
    template <class MemberPointerType> \
    static std::false_type testExistence(...); \
   \
    template <class MemberPointerType> \
    static decltype(testSignature(&MemberPointerType::FUNCTION)) testExistence(std::nullptr_t); \
public: \
    using type = decltype(testExistence<ClassType>(nullptr));\
    static const bool value = type::value; \
};


    class Bla
    {
    public:
        template <typename SomeType>
        bool init(SomeType someValue)
        {
            ///
            return true;
        }

        void exec()
        {
            return;
        }
    };

    CHECK4_MEMBER_FUNC(bool, init, int);
    CHECK4_MEMBER_FUNC(void, exec, void);

int main()
{
  Bla blaObj;
  blaObj.init<int>(2);
  static_assert(CIfCheck_exec<Bla>::value, "no exec");
  static_assert(CIfCheck_init<Bla>::value, "no init");

  return 0;
}

but unfortunately the static_assert is triggered for init (as the specialization is probably evaluated at a later time as the object is being instantiated in main()) . I tried with explicit member-specialization, but it is still failing:

template<>
bool Bla::init<int>(int item)
{
    int temp = item*2; // do with item something
    return false;
}
  • side-question (probably another question topic would make more sense:

    std::false_type testExistence(...); Why exactly do I have to pass an argument here? If I remove the variadic argument ... option (and nullptr and nullptr_t), the compiler errors due to ambiguous existence of testExistence().

Aucun commentaire:

Enregistrer un commentaire