Very weird problem I've been struggling with for the past few hours (after solving 5-6 other issues with SFINAE as I'm new to it). Basically in the following code I want to have f()
working for all possible template instantiations, but have g()
available only when N == 2
:
#include <type_traits>
#include <iostream>
template<typename T, int N>
class A
{
public:
void f(void);
void g(void);
};
template<typename T, int N>
inline void A<T, N>::f()
{
std::cout << "f()\n";
}
template<typename T, int N, typename std::enable_if<N == 2, void>::type* = nullptr>
inline void A<T, N>::g()
{
std::cout << "g()\n";
}
int main(int argc, char *argv[])
{
A<float, 2> obj;
obj.f();
obj.g();
return 0;
}
When I try to compile it I get an error about having 3 template parameters instead of two. Then, after some trials, I've decided to move the definition of g()
inside the definition of A
itself, like this:
#include <type_traits>
#include <iostream>
template<typename T, int N>
class A
{
public:
void f(void);
template<typename t = T, int n = N, typename std::enable_if<N == 2, void>::type* = nullptr>
void g()
{
std::cout << "g()\n";
}
};
template<typename T, int N>
inline void A<T, N>::f()
{
std::cout << "f()\n";
}
int main(int argc, char *argv[])
{
A<float, 2> obj;
obj.f();
obj.g();
return 0;
}
Now, magically everything works. But my question is WHY? Doesn't the compiler see that inside the class definition I'm trying to inline a member function that also depends on 3 template parameters? Or let's reverse the question: if it works inside A
's definition, why doesn't it work outside? Where's the difference? Aren't there still 3 parameters, which is +1 more than what class A
needs for its template parameters?
Also, why does it only work when I'm making the 3rd parameter a non-type one and not a type one? Notice I actually make a pointer of the type returned by enable_if and assign it a default value of nullptr, but I see I can't just leave it there as a type parameter like in other SO forum posts I see around here.
Appreciate it so much, thank you!!!