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:
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:
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!.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With