Re: Does taking address of function template specialization not force instantiation?
On 11 Apr., 19:50, Gerhard Menzl <clcppm-pos...@this.is.invalid>
wrote:
Consider:
#include <algorithm>
#include <vector>
template <typename Element,
typename Member,
Member (Element::*memPtr)()>
bool lessMember(Element const& left, Element const& right)
{
return (left.*memPtr)() < (right.*memPtr)();
}
This should not compile, because you are attempting to
apply a pointer to non-const member function to references
to const. Fix this to read:
template <typename Element,
typename Member,
Member (Element::*memPtr)() const>
bool lessMember(Element const& left, Element const& right)
{
return (left.*memPtr)() < (right.*memPtr)();
}
class C
{
public:
C(int i, long l) : m_i(i), m_l(l) {}
int GetInt() { return m_i; }
long GetLong() { return m_l; }
Given above fix, you also need to modify these member
declarations to:
int GetInt() const { return m_i; }
long GetLong() const { return m_l; }
private:
int m_i;
long m_l;
};
int main()
{
std::vector<C> vc;
static int const elementCount = 3;
for (int elem = 0; elem < elementCount; ++elem)
vc.push_back(C(elem, elementCount - elem));
// linker error without the following line uncommented
// bool b = lessMember<C, long, &C::GetLong>(vc[0], vc[1]);
std::sort(vc.begin(),
vc.end(),
lessMember<C, long, &C::GetLong>);
}
Unless the function template specialization lessMember<C, long,
&C::GetLong> is called explicitly, my compiler (Visual C++ 6.0) does not
instantiate the template and causes a linker error (unresolved
external).
Please excuse that I cannot resist to smile a bit, after having
read about the VC6 compiler in the context of templates... ;-)
Just taking the address of the specialization in the call to
std::sort does not seem to suffice. Is this one of the many limitations
of this outdated compiler, or does the Standard really not require an
instantiation here?
According to 14.7.1/2, a "function template specialization is implicitly
instantiated when the specialization is referenced in a context that
requires a function definition to exist". I would have assumed that
taking the address of a function (template specialization) requires its
definition.
The standard clearly says that a function must exist in this case.
This can be deduced by the combination of [basic.def.odr]/2:
"An overloaded function is used if it is selected by overload
resolution when referred to from a potentially-evaluated expression."
with [over.over]/1:
"A use of an overloaded function name without arguments is resolved in
certain contexts to a function, a pointer to function or a pointer to
member function for a specific function from the overload set. A function
template name is considered to name a set of overloaded functions in such
contexts.[..]"
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! ]