// Substitution Failure is Not an Error // (an example) // #include #include #include using namespace std; class A { public: typedef int multretT; A(int i) { x = i; } multretT mult(int y) const { return x*y; } private: int x; }; class B { public: typedef string multretT; B(int i) { x = i; } multretT mult(int y) const { stringstream ss; ss << x; string ret; for(;y>0;y--) ret += ss.str(); return ret; } private: int x; }; template typename T::multretT doubleit(const T &t) { return t.mult(2); } int doubleit(int x) { return x*2; } int main(int argc, char **argv) { A a(2); B b(3); int i=4; cout << doubleit(a) << endl; cout << doubleit(b) << endl; // for the call to doubleit below, the compiler // has to try to instantiate the templated version of doubleit // because int::multretT does not exist, instantiating this // version fails, BUT it is not an error (otherwise templates // would be much less useful). So, double(int) only matches // the second definition and all is well (no compiler errors). // // NOTE: SFINAE only applies when creating the function (or // struct/class) type, not when creating the "insides." Therefore, // if the signature of the function is fine, but inside the // function there is a compile error, that *is* a failure. cout << doubleit(i) << endl; }