Reputation: 1295
I have the following program (sorry, it is rather complex, but already a boiled-down version from a larger program):
#include <stdio.h>
// two different vector types
template <typename T, int N>
struct Vec1
{
Vec1() { puts("Vec1()"); }
};
template <typename T, int N>
struct Vec2
{
Vec2() { puts("Vec2()"); }
};
// a function wrapper
template <typename T, int N>
struct MyFct
{
template <template <typename, int> class VEC>
static inline VEC<T,N>
apply()
{
puts("MyFct::apply()");
return VEC<T,N>();
}
};
// tester
#if 0
template <typename T, int N, template <typename, int> class FCT>
struct Tester
{
static inline void test()
{
puts("Tester::test");
Vec1<T,N> v1;
v1 = FCT<T,N>::apply<Vec1>();
Vec2<T,N> v2;
v2 = FCT<T,N>::apply<Vec2>();
}
};
#endif
int
main()
{
MyFct<float,16>::apply<Vec1>();
MyFct<int,32>::apply<Vec2>();
// Tester<float,16,MyFct>::test();
return 0;
}
The program compiles with #if 0
(without Tester
), but with #if 1
(with Tester
) I get the error message
g++ -Wall -o templatetemplate2a templatetemplate2a.C
templatetemplate2a.C: In static member function 'static void Tester<T, N, FCT>::test()':
templatetemplate2a.C:41:30: error: missing template arguments before '>' token
v1 = FCT<T,N>::apply<Vec1>();
^
templatetemplate2a.C:41:32: error: expected primary-expression before ')' token
v1 = FCT<T,N>::apply<Vec1>();
^
templatetemplate2a.C:43:30: error: missing template arguments before '>' token
v2 = FCT<T,N>::apply<Vec2>();
^
templatetemplate2a.C:43:32: error: expected primary-expression before ')' token
v2 = FCT<T,N>::apply<Vec2>();
This is surprising since the direct application (see main()
) of apply<Vec1>()
and apply<Vec2>()
works fine. However, if I do the same inside of Tester::test()
, I get the error messages. Is this some name-scope issue? Are the template classes Vec1
and Vec2
unknown inside of Tester
? How can I make them known? Or is there some other problem?
Upvotes: 1
Views: 310
Reputation: 172914
apply()
is a member function template, you need to use the keyword template to tell the compiler that it's a template, when calling it with dependent name. Note the difference between FCT<T,N>
and MyFct<float,16>
, the former depends on template parameters FCT
, T
and N
, while the later doesn't.
Inside a template definition, template can be used to declare that a dependent name is a template.
e.g.
v1 = FCT<T,N>::template apply<Vec1>();
v2 = FCT<T,N>::template apply<Vec2>();
Upvotes: 3