about name lookup of friend function template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
namespace NS
{
	class A
	{
	public:
		A(){}
		A(int){}
	};
	
template<typename T>
	void foo(T);
};

using NS::A;

class B
{
public:
	B(int ii):i(ii){}
	friend void NS::foo(A);	    //1		
	//friend void foo(NS::A);  //2
private:
	int i;
};
template<typename T>
void NS::foo(T)
{
	::B c(10);
	std::cout<<c.i<<std::endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
	A t;
	foo(t);
	return 0;		
}


Hi,my question is why i can't use the friend declaration of explanatory note 2 to replace the friend declaration NS::foo of explanatory note 1. i think the function of explanatory note 2(by Argument-Dependent Lookup) and explanatory note 1 have the same effect, am i right?(in VC2008)
Last edited on
You can't do that because a template function must be entirely known before it can be used/instantiated (what you're trying to do on line 20)
If you specify unqualified-id for a friend function name then it is supposed that the function is an ordinary (non-template) function.
And the ADL is applied to arguments not to parameters.

Consider the following code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

namespace NS
{

	struct A {};

	template <typename T>
	void f( T ) { std::cout << "template <typename T> f( T )\n"; }

	struct B
	{
		friend void f( A );
	};

	void f( A ) { std::cout << "f( A )\n"; }
}

int main()
{
	NS::f( NS::A() );
}


You could write

friend void foo<A>(NS::A); //2

instead of

friend void foo(NS::A); //2

if you would want to make your template function a friend of the class.
Last edited on
About "And the ADL is applied to arguments not to parameters" . Why can not I think it like this:on line 20 I think because foo is a template function, NS::A is an argument for template not a parameter.And foo is a qualified-id for its template-arugment is qualified-id.
You are wrong. This statement

friend void NS::foo(A);

is a declaration of a friend function. So A is a declaration of its parameter that has type A. ADL is applied for function calls which uses unqualified function names.
Last edited on
Will a declaration of a friend function template lead a template instantion instantiation?
If I am not wrong it will not lead to instantiation until it will not be odr used.
Topic archived. No new replies allowed.