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;
}
P.S.: 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()
.