On 22 August 2012 19:49, Onay Urfalioglu wrote: > The following code compiles fine with g++-4.7.1 in c++11 mode, but I think > it should give errors for the last source line "auto res2 = 2 * > std::list<int>();" (SFINAE ?) I don't think it should. > // compile cmd: > // g++ c++11-test.cpp -o cpp11-test -std=c++11 > > #include <vector> > #include <list> > > template<typename T> > struct HasRandomAccessOp { > HasRandomAccessOp(const T &v) { > typedef decltype(v[0]) test_type; This type is only used in the body of the constructor. That means the constructor must be instantiated for the error to be detected. > } > }; > > template<typename T, typename T_VECTOR> > int operator*(const T &l, const T_VECTOR &r) { > typedef decltype(HasRandomAccessOp<T_VECTOR>(r)) > random_access_test_type; The constructor doesn't need to be instantiated for decltype to know the type of that expression, the type is obviously HasRandomAccessOp<T_VECTOR>. Even if the constructor was instantiated, SFINAE would not apply, because the error happens in the function body, not in the context where template argument deduction takes place, i.e. in determining the function signature by substituting the template arguments for the function parameter types and return type. > return 1; > } > > int main() { > std::vector<int> iv = {1,2}; > > auto res1 = 1 * iv; > auto res2 = 2 * std::list<int>(); > }