Point of instantiation is incomplete and should fail??

Hi,
I don't understand why this code compiles:

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
38
39
40
41
		class MyInt
		{
			int m_i;
		public:
			MyInt(int i)
				: m_i{i}
			{}
			int get() const { return m_i; }
		};

		MyInt operator-(MyInt const& a)
		{
			return MyInt(-a.get());
		}

		bool operator > (MyInt const& l, MyInt const& r)
		{
			return l.get() > r.get();
		}

		using Int = MyInt;

		template<typename T>
		void ff(T i)
		{
			if (i > 0)
			{
				gg(-i);
			}
		}

		void hh(Int x)
		{
			ff<Int>(x);
		}
		
		void gg(Int x)
		{
			ff<Int>(x);
		}


The point of instantiation of ff<Int> is (I assume) on the first appearance of such template id (thus inside function hh). But at that point, there has not been even a declaration for gg(Int) so how can ff<Int> compile?

Does it have to do with the first phase recognizing there is a gg in scope and then applying this knowledge in the second phase?

Regards,
Juan Dent
For a name used inside a member function body ... the entire scope of the class is considered, not just the part prior to the declaration that uses the name. http://en.cppreference.com/w/cpp/language/unqualified_lookup
But ff, gg and hh are not part of any class... did you misread the example?
the indentation might have thrown JLBorges off.

note that if you parenthesize or qualify gg, it won't compile:
1
2
3
prog.cc:28:6: error: use of undeclared identifier 'gg'
                                (gg)(-i);
                                 ^

1
2
3
prog.cc:28:7: error: no member named 'gg' in the global namespace
                                ::gg(-i);
                                ~~^

this implies the lookup that finds it is ADL lookup.

Specifically, if we use cppreference, http://en.cppreference.com/w/cpp/language/unqualified_lookup#Template_definition
ADL examines function declarations that are visible from the template definition context as well as in the template instantiation context [...] adding a new function declaration after template definition does not make it visible except via ADL

..although I suppose that's not quite precise enough to cover your case.. let's see if the standard is readable on this point.
Perhaps [temp.point]p8 is relevant:
for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation
. That gg is certainly visible from the end of the translation unit.
Or perhaps this is undefined due to [temp.dep.candidate]'s "If the call would find a better match had the lookup within the associated namespaces considered all the function declarations with external linkage introduced in those namespaces in all translation units[/quote]
Last edited on
Registered users can post here. Sign in or register to post.