lundi 17 juillet 2017

Why do C++ templates match if method doesn't type-check?

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.

Aucun commentaire:

Enregistrer un commentaire