Reputation: 355
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
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
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
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