user334066
user334066

Reputation: 355

Conversion of Function Pointer Non-Type Template Parameter to Type Template Parameters

The following example code compiles under gcc and works as I would hope. It allows me to instantiate an object with a function definition as a template parameter, but then the class is able to use the different types in the function as if they were passed individually as type template parameters.

template<class FuncSignature> class Obj;

template<class Type1, class Type2> class Obj<Type1 (Type2)>
{
public:
  Type1 var1;
  Type2 var2;
};

int main(int argc, char **argv)
{
  Obj<char (int)> A;
  A.var1 = 'a';
  A.var2 = 3;
}

Even though it seems to work, I'm not sure what this code is doing. Why does this code work and does it conform to the C++ standard?

Upvotes: 6

Views: 1012

Answers (3)

UncleBens
UncleBens

Reputation: 41351

Why shouldn't it work? The instantiation matches the specialization, which extracts the component types (char and int) of the compound type (a function, char(int)) as Type1 and Type2.

By the way, you don't have a non-type template parameter. A function type is a type. If you had a non-type template parameter, then it would look like this:

template <char(int)>
struct X {};

char foobar(int);

int main()
{
    X<foobar> x;
}

Or fully templated:

template <class R, class A, R(A)>
//                          ^^^^
//                      non-type parameter
struct X {};

char foobar(int);

int main()
{
    X<char, int, foobar> x;
//               ^^^^^^
//   a specific function, not type
}

Upvotes: 7

Palmik
Palmik

Reputation: 2665

Yes. This code conforms the standard :)

In the case of:

Obj<char (int)>

Type1 is char and Type2 is int. For that reason Obj::var1 is member variable of type char and Obj::var2 is member variable of type int.

Upvotes: 0

lijie
lijie

Reputation: 4871

This question is a misnomer because FuncSignature is not a non-type template parameter.

However, the code given works by specializing the (general) type FuncSignature for unary function types (Type1 (Type2) is a function type, given types Type1 and Type2).

So the first line defines a general template, the next group of lines specializes it for the type form Type1 (Type2), which are parameterized on two types, hence the specialization has a non-empty template parameter list, and the main instantiates the template for the concrete type char (int) (a function taking an int and returning a char).

Upvotes: 3

Related Questions