function template explicit specialization - c++

In this article, they are saying (c) explicit specialization of (b). My doubt is why can't we say it is explicit specialization of (a) ? because we can specialize the template for any particular type. so while specializing for int*, why they say (c) explicit specialization of (b) .
template<class T> // (a) a base template
void f( T );
template<class T> // (b) a second base template, overloads (a)
void f( T* ); // (function templates can't be partially
// specialized; they overload instead)
template<> // (c) explicit specialization of (b)
void f<>(int*);
Any comments will be helpful to understand the things.

If (b) didn't exist, then (c) would indeed be a valid specialisation of (a). In fact, just changing the order of the source lines so that (c) appears before the compiler has seen (b) will make it a specialisation of (a)!
Consider the following code:
int main()
{
int a;
f(&a);
return 0;
}
Now put yourself in the compiler's shoes. You need to find a matching function f with an int* argument. What do you do?
First, you try all the non-template functions called f that you know about, and see if there are any which match the argument types (in this case, int*).
If you can't get a perfect match, you look at all the base templates that you know about. In this case, there are two: f<T> and f<T*>. Note that unlike classes, function templates can't be partially specialised, so as far as the compiler is concerned these are completely separate overloads.
Clearly the f<T*> base template is a better match, so you instantiate it with T=int. Now, if you've already seen a specialisation for f<int*>, then you use that, and otherwise you generate the function.
Now here's the funny thing. If we change the order of your original code, to
template<class T> void f( T ); // (i)
template<> void f<>(int*); // (ii)
template<class T> void f( T* ); // (iii)
then the compiler now sees (ii) as a specialisation of (i) -- because it processes things in order, and at the point it reaches (ii) it doesn't know that (iii) exists yet! But since it only matches on base templates, it decides that (iii) is a better match than (i) -- and now (iii) does not have any specialisations, so you get the default instantiation.
It's all pretty confusing, and can trip up even the most experienced C++ programmers at times. So the basic rule is this: don't specialise function templates, but use normal function overloading instead. A regular old, non-template
void f(int*);
would be matched before anything else, and avoids this whole mess.
EDIT: n.m. requested references to the standard in the comments. I'm afraid I only have the C++03 version to hand, but here goes:
Paragraph 4.7.3.3: "A declaration of a function template or class template being explicitly specialized shall be in scope at the point of declaration of an explicit specialization.".
That's why in the above example, (ii) cannot be considered as an explicit specialisation of (iii), because (iii) is not yet in scope.
Section 4.8.3: "When a call to that [function] name is written... template argument deduction (14.8.2) and checking of any explicit template arguments (14.3) are performed for each function template to find the template argument values (if any) that can be used with that function template to instantiate a function template specialization that can be invoked with the call arguments."
In other words, (as I read it, anyway) it always looks at each base template no matter what -- providing an explicit specialisation makes no difference.
The same paragraph goes on: "For each function template, if the argument deduction and checking succeeds, the template-arguments (deduced and/or explicit) are used to instantiate a single function template specialization which is added to the candidate functions set to be used in overload resolution."
So it's only at this point (as I read it) that explicit specialisations get taken into account.
Lastly, and perhaps most importantly in this case, section 13.3.3 deals with choosing the "best viable function" in the overload set. Two items are relevant:
F1 is better than F2 if: "F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.5.2". This is why the f<T*> version gets picked ahead of the f<T> version when trying to match f(int*) -- because it's a "more specialised" template
F1 is better than F2 if: "F1 is a non-template function and F2 is a function template specialization", which was the basis for my advice at the end of the original answer.
Phew!

Related

Are all valid templates instantiated?

When I have multiple templates that could be instantiated, what happens?
template <typename T> void foo(T*);
template <typename T> void foo(T**);
template void foo(int**);
template <typename T> void foo(T*) { printf("called foo(T*)\n"); }
template <typename T> void foo(T**){ printf("called foo(T**)\n"); }
When we need to instantiate a foo(int**), either of the instantiations would work, one with T=int* and the other with T=int**. In practice, the object file only contains one, the T** one. On the other hand, if I put a static_assert(false) into the unused one, the compilation fails. Does that mean that it is instantiated?
It turns out that the T** is the one that I want to use in this case. But even if both were instantiated, overload resolution would pick the T** one, so this works for me either way.
Now in my actual code, I request two instantiations:
template void foo(int*);
template void foo(int**);
That instantiates foo<int>(int**) and foo<int>(int*), so I get both templates. The latter is forced, since template <typename T> foo(T**) doesn't match. But I don't understand the rules to know why I don't get foo<int*>(int**) for the former. Or both foo<int*>(int**) as well as foo<int>(int**).
And yes, I realize I could do template void foo<int*>(int**) if I needed to force it.
All this makes me realize I don't really understand what happens when the compiler sees a call that requires a template instantiation. Does it scan through templates until it finds one that works, then stop? Or does it instantiate all valid options (and then something discards the unneeded ones from the object file)?
Template argument deduction is performed to figure out what function template specialization is named by template void foo(int**);; it selects the T** one after considering partial ordering. See [temp.deduct.decl] and sections linked therein. That's roughly the same process used to pick the function template to call during overload resolution (with some minor differences).
There's no mechanism for instantiating everything that matches. If the compiler can't select a unique function template specialization, the program is simply ill-formed.
On the other hand, if I put a static_assert(false) into the unused one, the compilation fails. Does that mean that it is instantiated?
That's just [temp.res]/8 at work, as usual. Code that is ill-formed in a way that doesn't depend on a template parameter may be diagnosed immediately without instantiation.
if I put a static_assert(false) into the unused one, the compilation fails. Does that mean that it is instantiated?
No. The compiler does some basic checks on a template definition. Everything in the definition must be valid C++, but certain things which depend on a template parameter cannot be checked until an actual instantiation, when the template arguments are known. Since static_assert(false); does not depend on any template parameters, it always causes an error, and a compiler is allowed to note the error even when the template is never instantiated.
If you really want a template that should never be instantiated, the usual way is to use =delete for a function template, or leave a class template undefined.
But I don't understand the rules to know why I don't get foo<int*>(int**) for the former.
In most contexts that name a specialization of a function template, there's a rule that any template which is "more specialized" than all other viable overloads is the one that gets used. The exact definition of "more specialized" is a bit tricky, but the basic idea is that if any argument list that could be taken by a function template "A" could also be taken by a function template "B" but not vice versa, then "A" is more specialized. In your example
template <typename T> void foo(T*); // #1
template <typename T> void foo(T**); // #2
if an argument arg has type U** for any type U so that template argument deduction for template #2 for foo(arg) can succeed with T=U, we can see that template argument deduction for template #1 for foo(arg) can also succeed with T=U*. On the other hand, it's obviously possible that another argument arg2 can mean that template argument for foo(arg2) can succeed for template #1 but fail for template #2, for example if arg2 has type int*. So function template #2 is more specialized than function template #1. This means an expression like foo(arg), whenever type deduction for both succeeds (and there are no other viable overloads involved), means a use of template #2.
The same "more specialized" rule applies in your explicit instantiation
template void foo(int**);
Much like with a function call expression, the compiler will use template argument deduction to see whether the declaration you gave matches each function template. In this case both succeed, but since template #2 is more specialized, the declaration is interpreted as a specialization of #2 and not #1.
All this makes me realize I don't really understand what happens when the compiler sees a call that requires a template instantiation. Does it scan through templates until it finds one that works, then stop? Or does it instantiate all valid options (and then something discards the unneeded ones from the object file)?
The rough sequence for most uses of the name of an overloaded function template is:
Do name lookup to determine the list of function templates and functions to be considered.
For each function template in the list, attempt template argument deduction. If template argument deduction fails, or if substituting any template argument into the function type fails, ignore that template from here on. If successful, this results in a template argument for each template parameter, and one specific function type for the specialization.
Do overload resolution in mostly the same way as for non-templates, on the set of non-template functions initially looked up combined with the set of function template specializations determined above. But if two candidate functions cannot be ordered to say one is a better overload than the other just based on the parameter types and implicit conversions involved, then a non-template function beats a function template specialization, and a specialization from a more specialized function template beats a specialization from a less specialized function template.
Note that during this process, the function types but not the definitions of the function template specializations are instantiated.

What are the rules for choosing between a variadic template method and a usual template method?

I have two template operators in class:
template<class T>
size_t operator()(const T& t) const {
static_assert(boost::is_pod<T>(), "Not a POD type");
return sizeof t;
}
template<typename... T>
size_t operator()(const boost::variant<T...>& t) const
{
return boost::apply_visitor(boost::bind(*this, _1), t);
}
I pass boost::variant<some, pod, types, here> as an argument to these operators. GCC 4.8 and llvm 6.0 compile the code fine, choosing boost::variant parameterized operator. gcc 4.7 chooses const T& t parameterized operator and thus fails to compile due to static assert.
So, I have a question, what are the rules for choosing between these two?
I think gcc 4.7 must have a bug, but I don't have any proof.
The key section is in [temp.deduct.partial]:
Two sets of types are used to determine the partial ordering. For each of the templates involved there is
the original function type and the transformed function type. [ Note: The creation of the transformed type
is described in 14.5.6.2. —end note ] The deduction process uses the transformed type as the argument
template and the original type of the other template as the parameter template. This process is done twice
for each type involved in the partial ordering comparison: once using the transformed template-1 as the
argument template and template-2 as the parameter template and again using the transformed template-2
as the argument template and template-1 as the parameter template.
That's really dense, even for the C++ standard, but what it basically means is this. Take our two overloads:
template <class T> // #1
size_t operator()(const T& t) const
template <typename... T> // #2
size_t operator()(const boost::variant<T...>& t)
And we're going to basically assign some unique type(s) to each one and try to see if the other applies. So let's pick some type A for the #1, and B,C,D for #2. Does operator()(const A&) work for #2? No. Does operator()(const boost::variant<B,C,D>&) work for #1? Yes. Thus, the partial ordering rules indicate #2 is more specialized than #1.
And so, from [temp.func.order]:
The deduction process determines whether one of the templates is more specialized than the other. If
so, the more specialized template is the one chosen by the partial ordering process.
And from [over.match.best]:
[A] viable function F1 is defined to be a better function than another viable function
F2 if
— [..]
— F1 and F2 are function template specializations, and the function template for F1 is more specialized
than the template for F2 according to the partial ordering rules described in 14.5.6.2.
Thus, #2 should be chosen in any case where it applies. If GCC chooses #1, that is nonconforming behavior and is a bug.
In general the compiler just treats all deduced template instantiations as potential overloads, picking the "best viable function" (§ 13.3.3).
Indeed this means GCC 4.7 has a bug then.
See §14.8.3: Overload resolution
describes that all template instances will join in the set of candidates as any non-template declared overload:
A function template can be overloaded either by (non-template) functions of its
name or by (other) function templates of the same name. When a call to that
name is written (explicitly, or implicitly using the operator notation),
template argument deduction (14.8.2) and checking of any explicit template
arguments (14.3) are performed for each function template to find the template
argument values (if any) that can be used with that function template to
instantiate a function template specialization that can be invoked with the
call arguments. For each function template, if the argument deduction and
checking succeeds, the template- arguments (deduced and/or explicit) are used
to synthesize the declaration of a single function template specialization
which is added to the candidate functions set to be used in overload
resolution. If, for a given function template, argument deduction fails, no
such function is added to the set of candidate functions for that template. The
complete set of candidate functions includes all the synthesized declarations
and all of the non-template overloaded functions of the same name. The
synthesized declarations are treated like any other functions in the remainder
of overload resolution, except as explicitly noted in 13.3.3.
In the case of your question, the overloads end up being indistinguishable (credit: #Piotr S). In such cases "partial ordering" is applied (§14.5.6.2):
F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2
Note that things can get pretty tricky, when e.g. the "open template" version took a T& instead of T const& (non const references are preferred, all else being equal).
When you had several overloads that end up having the same "rank" for overload resolution, the call is ill-formed and the compiler will diagnose an ambiguous function invocation.

What is the partial ordering procedure in template deduction

Reading the C++11 standard I can't fully understand the meaning of the following statement. Example are very welcome.
Two sets of types are used to determine the partial ordering. For each
of the templates involved there is the original function type and the
transformed function type. [Note: The creation of the transformed type
is described in 14.5.6.2. — end note ] The deduction process uses the
transformed type as the argument template and the original type of the
other template as the parameter template. This process is done twice
for each type involved in the partial ordering comparison: once using
the transformed template-1 as the argument template and template-2 as
the parameter template and again using the transformed template-2 as
the argument template and template-1 as the parameter template
-- N3242 14.8.2.4.2
While Xeo gave a pretty good description in the comments, I will try to give a step-by-step explanation with a working example.
First of all, the first sentence from the paragraph you quoted says:
For each of the templates involved there is the original function type and the transformed function type. [...]
Hold on, what is this "transformed function type"? Paragraph 14.5.6.2/3 explains that:
To produce the transformed template, for each type, non-type, or template template parameter (including
template parameter packs (14.5.3) thereof) synthesize a unique type, value, or class template respectively
and substitute it for each occurrence of that parameter in the function type of the template [...]
This formal description may sound obscure, but it is actually very simple in practice. Let's take this function template as an example:
template<typename T, typename U>
void foo(T, U) // #1
Now since T and U are type parameters, the above paragraph is asking us to pick a corresponding type argument for T (whatever) and substitute it everywhere in the function signature where T appears, then to do the same for U.
Now "synthesizing a unique type" means that you have to pick a fictitious type you haven't used anywhere else, and we could call that P1 (and then pick a P2 for U), but that would make our discussion uselessly formal.
Let's just simplify things and pick int for T and bool for U - we're not using those types anywhere else, so for our purposes, they are just as good as P1 and P2.
So after the transformation, we have:
void foo(int, bool) // #1b
This is the transformed function type for our original foo() function template.
So let's continue interpreting the paragraph you quoted. The second sentence says:
The deduction process uses the transformed type as the argument template and the original type of the other template as the parameter template. [...]
Wait, what "other template"? We only have one overload of foo() so far. Right, but for the purpose of establishing an ordering between function templates, we need at least two of them, so we'd better create a second one. Let's use:
template<typename T>
void foo(T const*, X<T>) // #2
Where X is some class template of ours.
Now what with this second function template? Ah, yes, we need to do the same we previously did for the first overload of foo() and transform it: so again, let's pick some type argument for T and replace T everywhere. I'll pick char this time (we aren't using it anywhere else in this example, so that's as good as some fictitious P3):
void foo(char const*, X<char>) #2b
Great, now he have two function templates and the corresponding transformed function types. So how to determine whether #1 is more specialized than #2 or vice versa?
What we know from the above sentence is that the original templates and their transformed function types must be matched somehow. But how? That's what the third sentence explains:
This process is done twice for each type involved in the partial ordering comparison: once using the transformed template-1 as the argument template and template-2 as the parameter template and again using the transformed template-2 as the argument template and template-1 as the parameter template
So basically the transformed function type of the first template (#1b) is to be matched against the function type of the original second template (#2). And of course the other way round, the transformed function type of the second second template (#2b) is to be matched against the function type of the original first template (#1).
If matching will succeed in one direction but not in the other, then we will know that one of the templates is more specialized than the other. Otherwise, neither is more specialized.
Let's start. First of all, we will have to match:
void foo(int, bool) // #1b
Against:
template<typename T>
void foo(T const*, X<T>) // #2
Is there a way we can perform type deduction on T so that T const* becomes exactly int and X<T> becomes exactly bool? (actually, an exact match is not necessary, but there are really few exceptions to this rule and they are not relevant for the purpose of illustrating the partial ordering mechanism, so we'll ignore them).
Hardly. So let's try matching the other way round. We should match:
void foo(char const*, X<char>) // #2b
Against:
template<typename T, typename U>
void foo(T, U) // #1
Can we deduce T and U here to produce an exact match for char const* and X<char>, respectively? Sure! It's trivial. We just pick T = char const* and U = X<char>.
So we found out that the transformed function type of our first overload of foo() (#1b) cannot be matched against the original function template of our second overload of foo() (#2); on the other hand, the transformed function type of the second overload (#2b) can be matched against the original function template of the first overload (#1).
Conclusion? The second overload of foo() is more specialized than the first one.
To pick a counter-example, consider these two function templates:
template<typename T, typename U>
void bar(X<T>, U)
template<typename T, typename U>
void bar(U, T const*)
Which overload is more specialized than the other? I won't go through the whole procedure again, but you can do it, and that should convince you that a match cannot be produced in either direction, since the first overload is more specialized than the second one for what concerns the first parameter, but the second one is more specialized than the first one for what concerns the second parameter.
Conclusion? Neither function template is more specialized than the other.
Now in this explanation I have ignored a lot of details, exceptions to the rules, and cryptic passages in the Standard, but the mechanism outlined in the paragraph you quoted is indeed this one.
Also notice, that the same mechanism outlined above is used to establish a "more-specialized-than" ordering between partial specializations of a class template by first creating an associated, fictitious function template for each specialization, and then ordering those function templates through the algorithm described in this answer.
This is specified by paragraph 14.5.5.2/1 of the C++11 Standard:
For two class template partial specializations, the first is at least as specialized as the second if, given the
following rewrite to two function templates, the first function template is at least as specialized as the second
according to the ordering rules for function templates (14.5.6.2):
— the first function template has the same template parameters as the first partial specialization and has
a single function parameter whose type is a class template specialization with the template arguments
of the first partial specialization, and
— the second function template has the same template parameters as the second partial specialization
and has a single function parameter whose type is a class template specialization with the template
arguments of the second partial specialization.
Hope this helped.

C++ Template Formal Ordering Rules

I'm having difficulty understanding the how formal ordering rules work as described in chapter 12 of the book C++ Templates, The Complete Guide by D. Vandevoorde and N. M. Josuttis. On page 188 of this book the authors give the following scenario used to decide which of two viable function templates is more specialized:
From these two templates we synthesize two lists of argument types by replacing the template parameters as described earlier: (A1) and (A2*) (where A1 and A2 are unique made up types). Clearly, deduction of the first template against the second list of argument types succeeds by substituting A2* for T. However, there is no way to make T* of the second template match the nonpointer type A1 in the first list. Hence, we formally conclude that the second template is more specialized than the first.
I'd like some understanding this example.
Edit
I believe that the two function templates referred to in the above quote are
template<typename T>
int f(T)
{
return 1;
}
template<typename T>
int f(T*)
{
return 2;
}
The rules are a bit harder to explain than to use. The idea is that a template is more specialized than another template if the set of possible instantiations of the more specialized is a strict subset of the set of possible instantiations of the less specialized one.
That is, every type that can be use as an argument to the more specialized can also be used as argument to the less specialized, and there is at least one type that can be used with the less specialized that cannot be used with the more specialized.
Given the two templates:
template <typename A> void f( A ); // [1]
template <typename B> void f( B* ); // [2]
The question to resolve is which one of them is more generic (i.e. can take a greater number of arguments). The whole description in the standard is done in terms of synthetic unique types that are used for A and B, but in a less precise way we can try to resolve by hand waving.
Say we find a type X that matches the second template argument, then an instantiation of that second template will look like void f( X* ) (besides the fact that it is a template). Now, can the template [1] be used to generate an equivalent function? Yes, by making A == X* in the type deduction. Can we do it in the opposite direction? Say we find a type Y with which we can instantiate the first template, we get void f( Y ). Can the second template match this call? No, only for the subset of types that are pointers the previous statement can hold.
That means that the second template is more specialized, since for every valid instantiation of the second template, we can also instantiate the first template, but there are some instantiations of the first template that would not be valid instantiations of the second.
For a practical example, f( char* ) can be matched by both templates, but f( 5 ) can only be matched by the first one. The reason for the weird explanation in terms of synthetic types is that a single example does not guarantee the order, it has to hold for all types. The synthetic type is a representative of any type.
I think the point of the authors is that T in the first template can be matched to both a type A and a pointer to a type A*, while the second template can only be matched to a pointer to a type A*, therefore the second template is more specialized.

Template argument deduction from function body

If we've this function template,
template<typename T>
void f(T param) {}
Then we can call it in the following ways,
int i=0;
f<int>(i);//T=int : no need to deduce T
f(i); //T=int : deduced T from the function argument!
//likewise
sample s;
f(s); //T=sample : deduced T from the function argument!
Now consider this variant of the above function template,
template<typename TArg, typename TBody>
void g(TArg param)
{
TBody v=param.member;
}
Now, can the compiler deduce the template arguments if we write,
sample s;
g(s); //TArg=sample, TBody=int??
Suppose sample is defined as,
struct sample
{
int member;
};
There are basically two questions:
Can the compiler deduce the template arguments in the second example?
If no, then why? Is there any difficulty? If the Standard doesn't say anything about "template argument deduction from function body", then is it because the argument(s) cannot be deduced? Or it didn't consider such deduction so as to avoid adding more complexity to the language? Or what?
I would like know your views on such deduction.
EDIT:
By the way, the GCC is able to deduce function arguments if we write this code:
template<typename T>
void h(T p)
{
cout << "g() " << p << endl;
return;
}
template<typename T>
void g(T p)
{
h(p.member); //if here GCC can deduce T for h(), then why not TBody in the previous example?
return;
}
Working demonstration for this example : http://www.ideone.com/cvXEA
Not working demonstration for the previous example: http://www.ideone.com/UX038
You probably already concluded that the compiler won't deduce TBody by examining the type of sample.member. This would add yet another level of complexity to the template deduction algorithm.
The template matching algorithm only considers function signatures, not their bodies. While not used too often, it's perfectly legal to simply declare a templated function without providing the body:
template <typename T> void f(T param);
This satisfies the compiler. In order to satisfy the linker, you must of course also define the function body somewhere, and ensure that all required instantiations have been provided. But the function body does not necessarily have to be visible to client code of the template function, as long as the required instantiations are available at link time. The body would have to explicitly instantiate the function, eg:
template <> void f(int param);
But this only partially applies to your questions, because you could imagine a scenario like the following, where a 2nd parameter could be deduced from the a provided default parameter, and which won't compile:
template<typename TArg, typename TBody>
void g(TArg param, TBody body = param.member); // won't deduce TBody from TArg
The template matching algorithm considers only the actual type, not any potential nested member types in case of classes or structs. This would have added another level of complexity which apparently was judged to be too complex. Where should the algorithm stop? Are members of members, and so forth, also to be considered?
Also, it's not required because there are other means of achieving the same intention, as shown in the example below.
Nothing prevents you from writing:
struct sample
{
typedef int MemberType;
MemberType member;
};
template<typename TArg>
void g(TArg param)
{
typename TArg::MemberType v = param.member;
}
sample s = { 0 };
g(s);
in order to obtain the same effect.
Regarding your sample you added after editing: whereas it seems that h(p.member) does depend on the member of the struct, and hence the template matching algorithm should fail, it doesn't because you made it a two-step process:
Upon seeing g(s);, the compiler looks for any function taking an argument of type sample (templated or not!). In your case, the best match is void g(T p). At this point, the compiler has not even looked at the body of g(T p) yet!.
Now, the compiler creates a instance of g(T p), specialized for T: sample. So when it sees h(p.member) it knows that p.member is of type int, and will try locate a function h() taking an argument of type int. Your template function h(T p) turns out to be the best match.
Note that if you had written (note the NOT_A_member):
template<typename T>
void g(T p)
{
h(p.NOT_A_member);
return;
}
then the compiler would still consider g() a valid match at stage 1. You then get an error when it turns out that sample does not have a member called NOT_A_member.
There are a couple of things that the compiler cannot possibly do with the code that you provide, the first of which is deduce the second template argument TBody. First, type deduction is only applied to the arguments of the function when the compiler is trying to match the call. At that point the definition of the templated function is not even looked at.
For extra credits, even if the compiler were to look the function definition, the code TBody v = parameter.member is non-deducible in itself, as there are potentially infinite data types that can accept a parameter.member in the constructor.
Now, on the second block of code. To understand it the whole process of template compilation starts when the compiler sees the function call g(x) at that point of call. The compiler sees that the best candidate is the template function template <typename T> void g( T ) and determines what the type T is as part of the overload resolution. Once the compiler determines that it is a call to the template, it performs the first pass of compilation on that function.
During the first pass, syntactic checks are perform without an actual substitution of the type, so the template argument T is still any-type and the argument p is of a yet-unknown type. During the first pass, the code is verified, but dependent names are skipped and their meaning is just assumed. When the compiler sees p.member, and p is of type T that is a template argument it assumes that it will be a member of the yet unknown type (this is the reason why if it is a type you would have to qualify it here with typename). The call h(p.member); is also dependent on the type argument T and is left as it is, assuming that once the type substitution takes place everything will make sense.
Then the compiler does actually substitute the type. At this step T is no longer a generic type, but it represents the concrete type sample. Now the compiler during the second pass tries to fill in the gaps that were left during the first pass. When it sees p.member it looks member inside the type and determines that it is an int and tries to resolve the call h( p.member ); with that knowledge. Because the type T has been resolved before this second stage, this is equivalent to the outside call g(x): all types are known and the compiler only needs to resolve what is the best overload for a function call h that takes an argument of type int&, and the whole process starts again, the template h is found as the best candidate, and ...
It is really important for metaprogramming to understand that type deduction is performed only on the actual signature of the function and not the body, and that is what makes it non-trivial for beginners. Using enable_if (from boost or elsewhere) in the function signature as argument or return type is not a coincidence, but the only way of having the compiler fail to substitute the type before the template is selected as best candidate and the substitution failure is turned into an actual error (and not SFINAE)
No compiler could possibly implement this functionality in a consistent manner. You are simply asking too much.
TBody might be ambiguous, because sample might not be the only type that has a member member. Furthermore, if g calls other template functions, the compiler has no way of knowing what other restrictions might be imposed on TBody.
So in some edge cases, it is theoretically possible to deduce the proper type for TBody, generally it is not.