With regards to your first question – about the type int(char, float)
– this is a valid C++ type and is the type of a function that takes in a char
and a float
and returns an int
. Note that this is the type of the actual function, not a function pointer, which would be an int (*) (char, float)
. The actual type of any function is this unusual type. For example, the type of
void DoSomething() {
/* ... */
}
is void ()
.
The reason that this doesn’t come up much during routine programming is that in most circumstances you can’t declare variables of this type. For example, this code is illegal:
void MyFunction() {
void function() = DoSomething; // Error!
}
However, one case where you do actually see function types used is for passing function pointers around:
void MyFunction(void FunctionArgument()) {
/* ... */
}
It’s more common to see this sort of function written to take in a function pointer, but it’s perfectly fine to take in the function itself. It gets casted behind-the-scenes.
As for your second question, why it’s illegal to have the same template written with different numbers of arguments, I don’t know the exactly wording in the spec that prohibits it, but it has something to do with the fact that once you’ve declared a class template, you can’t change the number of arguments to it. However, you can provide a partial specialization over that template that has a different number of arguments, provided of course that the partial specialization only specializes over the original number of arguments. For example:
template <typename T> class Function;
template <typename Arg, typename Ret> class Function<Ret (Arg)> {
/* ... */
};
Here, Function
always takes one parameter. The template specialization takes in two arguments, but the specialization is still only over one type (specifically, Ret (Arg)
).