By looking at the following code, I am confused by line 3.
Line 3 is not a special case of the base template, it is more like a "class overload". But it can be compiled successfully. The obj1 in line 7 is defined according to line 3, but failed to compile. How come?template<typename S,int T, void(* U)()> class Bar{}; // Base template
template<int T, void(* U)()> class Bar<double, T, U>{}; // 开发者_开发知识库Specialization, which is good
template<int T, void(* U)()> class Bar<double, U, T>{}; // Also good, how come?
void func(){};
int main(){
//Bar<double, func, 1> obj1; // Error, from line 3
}
Templates are special: anything that you do not use is not actually instantiated (compiled). This allows many cool things to be done with certain generic templates. For example, you could define member functions that simply would not compile with certain type parameters, but as long as you would not use those members, no error.
This can also bite you: Line 3 isn't actually well-formed - it's a non-compiling specialization of Bar - but you won't notice it until you actually try to use it, in your main() function.
As long as that form is not used anywhere - then the compiler will not complain. If it is used, and the compiler has to instantiate - then it will complain. Which is why if you uncomment, you get the error - at this point, the compiler sees the flawed partial specialization.
精彩评论