Re: Function template argument deduction
Am 02.03.2012 21:30, schrieb Cpp_Learner:
Consider the code snippet below.
The code snippet fails to compile with the error message "error: no
matching function for call to 'beta(A<char>*&)'" on gcc.
The compiler is correct.
Given that "aA" is of the type "A<char>::Aptr", I was expecting that
the call "beta(aA)" will get resolved to the function template
"template<typename T> void beta(typename A<T>::Aptr a)", with "T" as
"char".
No, the compiler cannot deduce *any* argument type from such a
construction. This is what the standard describes as a "non-deduced
context". The reason for this is, because templates can be specialized,
which means that the compiler cannot safely conclude what T is based on
some known type A<T>::Aptr. You may think that this works, because you
only provided a single specialization (the primary template). But in
general, arbitrary specializations may be provided, e.g. consider
template<>
struct A<int>
{
typedef bool* Aptr;
};
or
template<>
struct A<unsigned>
{
typedef void Aptr;
};
or anything else.
I am kind of puzzled with this, and wanted to learn why the compiler
is unable to resolve this. I do not see any issues if I modify the
call site to beta<char>(aA).
You don't see any issue here, because you explicitly provide the
template argument, thus the compiler just accepts the type. Given some
T, it can find the correct instantiation A<char>, it sees that it has
the type A<char>::Aptr of type A<char>* - done.
The snippet of code is related to some work I am doing on templatizing
some old code to support additional types. I really would like to
avoid this additional specification of template type at call site to
keep things simple, and wanted to know if there are any workarounds
that would not need me to modify the call sites.
You need a different strategy. E.g. you could add an inline friend in
template A:
template<typename T>
struct A
{
typedef A<T> *Aptr;
friend void beta(Aptr a) { /**/ }
};
This works because such a friend function is considered as a
non-function template and thus there will be no argument type deduction
taking place (it works only if at least one function parameter depends
on A). A definition of a free function will only be created when beta is
odr-used.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]