The follow code does not compile because struct A
doesn't support the --
operator.
struct A {};
struct B {
void Run() {}
A& Dec(A& a) { return --a; }
};
int main(int argc, char** argv) {
B b;
b.Run();
}
Same with this code.
struct A {};
template <class T>
struct B {
void Run() {}
A& Dec(A& a) { return --a; }
};
int main(int argc, char** argv) {
B<A> b;
b.Run();
}
So why does this compile (in C++11)?
struct A {};
template <class T>
struct B {
void Run() {}
T& Dec(T& a) { return --a; }
};
int main(int argc, char** argv) {
B<A> b;
b.Run();
}
It appears that instantiating the template does not automatically instantiate unused methods within the template that depend on the type parameter to type-check, which means that the template will match even if some of its methods don't. It's disappointing because I was hoping to use SFINAE to detect the applicability of various methods and operators to types, but if template substitution succeeds even when calls to the methods would be compile-time errors, the technique won't work.