Reputation: 3922
In code below what is the difference between <Result (Arg0, Arg1)>
and <Result, Arg0, Arg1>
#include <cstddef>
#include <iostream>
using namespace std;
template <typename Result, typename Arg0 = void, typename Arg1 = void>
class Signal;
template <typename Result, typename Arg0, typename Arg1>
class Signal<Result (Arg0, Arg1)> // is this the same as <Result, Arg0, Arg1>
{
Result test(Arg0 arg0, Arg1 arg1)
{
}
};
int main()
{
Signal<void (int, int)> s; // or Signal<void, int, int>?
}
Upvotes: 4
Views: 1047
Reputation: 180955
The difference between <Result (Arg0, Arg1)>
and <Result, Arg0, Arg1>
is the the former is a single type (that of a function), with nested types in it, while the latter if 3 separate types.
Functions in C++ has a type. Without getting into everything that is part of the type generally it will be
return_type(paramter_type1, paramter_type1, ..., paramter_typeN)
So, for a function like int foo(double, char)
, its type is int(double, char)
. What your specialization does is allow you to pass a function type to the template and it will deduce the parameters from that, instead of having you specify them yourself. That would look like
int foo(double, char);
Signal<decltype(foo)> s;
Upvotes: 4
Reputation: 29193
Result(Arg0, Arg1)
is a single type. It is read "function taking Arg0
and Arg1
returning Result
". When you specialize Signal
,
template <typename Result, typename Arg0, typename Arg1>
class Signal<Result(Arg0, Arg1)>
you've only given 1 argument, but it takes 3. The other 2 become the defaults, as stated in the template declaration. Thus, this is the same as
template <typename Result, typename Arg0, typename Arg1>
class Signal<Result(Arg0, Arg1), void, void>
Note that it makes absolutely no difference that the name of the parameters in the specialization match up with the declaration. The Arg0
in the specialization is different from the Arg0
in the declaration. In the specialization, Arg0
-from-the-declaration is not specified, which is why it defaults to void
. Similarly, in the declaration
Signal<void(int, int)> s;
you've really written
Signal<void(int, int), void, void> s;
I doubt you meant to do either of these things. Just use commas.
Upvotes: 7
Reputation: 26186
No, it isn't the same. This:
Result (Arg0, Arg1)
is the type of a function taking two arguments, of types Arg0
and Arg1
and returning a result of type Result
.
Upvotes: 2