I am trying to write a function, let's call it Base
, which takes Derived
as a template parameter and is also the base class of Derived
, which defines a method if a certain method in Derived
is defined.
Here is how I've attempted to implement this (derived from response to this question: How to let a base method be defined only if the derived class does not define a method of the same name)
#include <utility>
struct GetValueImpl
{
template <typename T>
static auto test(int) -> decltype(
std::declval<T&>().GetValue(0),
std::true_type{});
template <typename...>
static std::false_type test(...);
};
template <typename T>
struct GetValueDefined : public decltype(GetValueImpl::test<T>(0)) {};
template <typename Derived, int X>
class Base
{
public:
// I want to define this function only if GetValue is defined in Derived
template <typename... Args>
auto Test(const Args&...) -> typename std::enable_if<GetValueDefined<Derived>::value>::type
{
}
};
template <std::int32_t val>
class DerivedExample : public Base<DerivedExample<val>, 1>
{
public:
template <typename T>
int GetValue() {return 0;}
};
int main() {
DerivedExample<1> d;
d.Test(1, 2);
return 0;
}
This produces the following compiler error:
prog.cpp:21:10: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
auto Test(const Args&...) -> typename std::enable_if<GetValueDefined<Derived>::value>::type
^
prog.cpp: In function ‘int main()’:
prog.cpp:36:7: error: ‘class DerivedExample<1>’ has no member named ‘Test’
d.Test(1, 2);
^
Clearly my std::enable_if
check is failing. But why?