Reputation: 101456
#include <cstdlib>
template<class A> struct Foo
{
template<class B> static bool Bar();
};
template<class B> template<class A> bool Foo<A>::Bar<B>()
{
return true;
}
int main()
{
bool b = Foo<int>::Bar<long>();
b;
}
This results in a linker error:
main.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl Foo<int>::Bar<long>(void)" (??$Bar@J@?$Foo@H@@SA_NXZ) referenced in function main
I need to define this member function outside of the class template's declaration. In other words, I cannot do this:
#include <cstdlib>
template<class A> struct Foo
{
template<class B> static bool Bar()
{
return true;
}
};
int main()
{
bool b = Foo<int>::Bar<long>();
b;
}
What am I missing? How can I define this member function template? What's the needed syntax?
Note: I am using MSVC 2008, in case that's relevant.
EDIT
The first thing I tried was to reverse the order of template<class A>
and template<class B>
:
#include <cstdlib>
template<class A> struct Foo
{
template<class B> static bool Bar();
};
template<class A> template<class B> bool Foo<A>::Bar<B>()
{
return true;
}
int main()
{
bool b = Foo<int>::Bar<long>();
b;
}
This resulted in a compiler error:
.\main.cpp(11) : error C2768: 'Foo<A>::Bar' : illegal use of explicit template arguments
On the closing brace of the definition for the Bar
function.
Upvotes: 4
Views: 230
Reputation: 137780
Just reverse the order of template<class B> template<class A>
. The second one is "inner" and goes with the member declaration. See §14.5.2/1.
Also, as John points out, remove the parameter-list from Bar<B>
.
// "outer" template: this parameter gets substituted to create "inner" template
template< class A >
// "inner" template stands alone after "outer" substitution
template< class B >
bool
// This will just be a class name after "outer" substitution.
foo<A>
// This has usual function template syntax
:: Bar() {
Upvotes: 3
Reputation: 36497
This works for me:
template<class A>
template<class B>
bool Foo<A>::Bar()
{
return true;
}
The order in which you write the two template
specifiers matters (the outer template comes first). Also, if you actually put <B>
on the name of the function template, at least one compiler (GCC) thinks you're trying to partially specialize the function Bar
, which is impossible.
Upvotes: 2