I want to define a template class Foo<T>
and a template function func<T>
, so that func<T>
is a friend of Foo<T>
, but func<T1>
is NOT a friend of Foo<T2>
for T1 != T2
. As far as I know, there are two ways to do this.
1:
template < typename T >
class Foo;
template < typename T >
void func(Foo<T> x);
template < typename T >
class Foo {
friend void func<>(Foo<T>);
};
template < typename T >
void func(Foo<T> x) {}
2:
template < typename T >
class Foo;
template < typename T >
void func(Foo<T> x);
template < typename T >
class Foo {
friend void func(Foo) {}
};
In both cases I can call func
like this
int main(void) {
Foo<int> a;
func(a);
But when I try to get a function pointer
(&func)(a);
}
the second version fails with a linker error:
/tmp/ccOICrUD.o: In function `main':
foo2.cpp:(.text+0x2c): undefined reference to `void func<int>(Foo<int>)'
collect2: error: ld returned 1 exit status
Why is that? And how do I get a function pointer to a function as in #2 above?
template < typename T >
void func(Foo<T> x);
This declares, but does define, a template function.
template < typename T >
class Foo {
friend void func(Foo) {}
};
This does not define the template and make it a friend. This effectively defines a non-template function
void func(foo<T>)
{
}
as a friend.
This is not the same thing as a template function. If you want to reference the template function, then you would do this:
template < typename T >
class Foo {
friend void func<>(Foo);
};
Just like as in your first example. Now, neither
func(a);
nor
(&func)(a);
links, because, of course, you have not defined the template function, in your second case. And once it's defined, you effectively have the same program as your first example.