The first case is permitted by the standard; I remember what @Johannes asked and answered @ Nawaz. (Edit: Here is a related question ).
The reason for not allowing the template version is because the template functions are only called with an explicit instance. In your case, the compiler looks at the declaration as
test<int> t;
-> Edit : it may be different from the compiler. In gcc, it works fine . <-
Why this may not work in the compiler may be . Since you are not explicitly creating an instance as t(N) , the compiler will not be able to resolve test<T>::test(int n = 666) . Thus, it searches for a default constructor without an argument that is not found; leading to an error.
source share