Reputation: 2553
template <typename T>
struct A {
void mem_func() {
// This works!!! Can access static_func<int>();
std::cout << T::template static_func<int>() << '\n';
}
template <typename K>
static constexpr bool static_func() { return true; }
template <typename T1>
typename std::enable_if<T::template static_func<T1>(), void> sfinae_func() {
// This breaks!!! T is an incomplete type??
std::cout << "This fails" <<'\n';
}
};
struct B : A<B> {
};
Here, I don't get why T::static_func is working in the member function foo() but when I go to instantiate the sfinae_func the same T::static_func is inaccessible as T is incomplete! How can this be??
Follow Up is this: If the standards restricts me to access T::static_func in enable_if, is there a workaround to hide A::static_funct with T::static_func when required?
template <typename T1>
typename std::enable_if<T::template static_func<T1>(), void> sfinae_func()
Here what would need to be done to have enable if call T's static_func such that T's static_func hides A's static_func?
Upvotes: 2
Views: 220
Reputation: 13988
To workaround the problem you could delay type instantiation by making T
of sfinae_func
additional template parameter's default value e.g. as follows (oh and don't forget to use inner type of std::enable_if
to actually perform sfinae):
#include <iostream>
template <typename T>
struct A {
void mem_func() {
std::cout << T::template static_func<int>() << '\n';
}
template <typename K>
static constexpr bool static_func() { return true; }
template <typename T1, typename TT = T>
typename std::enable_if<TT::template static_func<T1>(), void>::type sfinae_func() {
std::cout << "This fails" <<'\n';
}
};
struct B : A<B> {
};
int main() {
B a;
a.mem_func();
a.sfinae_func<int>();
}
Upvotes: 3