pmoubed
pmoubed

Reputation: 3922

Using Parentheses in Partial Template Specialization

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

Answers (3)

NathanOliver
NathanOliver

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

HTNW
HTNW

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

Acorn
Acorn

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

Related Questions