From: Daniel Krügler on
On 11 Apr., 19:50, Gerhard Menzl <clcppm-pos...(a)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! ]

From: Greg Herlihy on
On Apr 14, 9:35 am, Gerhard Menzl <clcppm-pos...(a)this.is.invalid>
wrote:
>
> Sorry, the consts were in the original code I compiled, they must have
> disappeared in reducing the code to the minimum. Since the error only
> occurs at link time, using Comeau online to test the code is not an option.

Then use Dinkumware's "Exam-" web-page of C++ compilers:

http://dinkumware.com/exam/default.aspx

According to that page, Visual C++ 6 and 7 both fail to link your
program - whereas Visual C++ 8.0 (both Express and Standard versions)
succeed. So a compiler upgrade might be in order.

> > 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.[..]"
>
> Thanks for pointing me to these passages, but I find them anything but
> clear. Does this really apply to taking the address of the function
> template specialization?

Yes, see also �14.8.2.2 "Deducing template arguments taking the
address of a function template" The C++ program in question invokes
the lessMember function specialization - so the compiler needs to
instantiate it.

Greg


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 14 Apr., 18:35, Gerhard Menzl <clcppm-pos...(a)this.is.invalid>
wrote:
> Daniel Kr�gler wrote:
> > 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.[..]"
>
> Thanks for pointing me to these passages, but I find them anything but
> clear. Does this really apply to taking the address of the function
> template specialization?

Let's unroll it from end to begin: [over.over] provides the rules
about "Address of overloaded function" and p.1 (quoted above)
just describes the syntactic manifold of taking the pointer to
a (free or static member) function, pointer to member function, etc.
It clarifies in this context that any function template used
like this follows the same rules as a "set of overloaded" functions.
The last point is important, because it gives us the correct
link to what entity we have to refer for.

I assume that you hesitation is based on the fact that [over.over]
speaks of a "template name" and not of a "template id". If so, your
hesitation is primarily profound, because this paragraph does not
*clearly* say whether it wants to include the case of a template with
explicitly specified template arguments. But at this point this
case is not explicitly excluded. To be sure we have to read a
bit further (and I apologize for not providing this information in
the first place) in p.2:

"If the name is a function template, template argument deduction is
done (14.8.2.2), and if the argument deduction succeeds, the
resulting
template argument list is used to generate a single function template
specialization, which is added to the set of overloaded functions
considered."

Note that this paragraph speaks of "resulting template argument list"
which includes the case of explicitly provided arguments. This
wording was chosen as part of

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#250

to express exactly this intend.

The quote of [basic.def.odr] is relevant, because if defines the
term of "usage" and thus implies the existence of the definition
of the offending function.

Even though you will find a lot of issues regarding [over.over],
these are actually all issues which clarify situations that could
be interpreted to lead to ambiguities or ill-formed code (E.g.
#250 belongs to this category). Obviously the VC6 compiler does
not cause this kind of problems here, because according to your
description the code *compiles* and is well-formed. There is no
doubt, that the expression

std::sort(vc.begin(),
vc.end(),
lessMember<C, long, &C::GetLong>);

is "potentially evaluated" and that a given specialization of
lessMember *is used*, otherwise this code would not make much
sense. Taking all this together I would say that this is a clear
compiler or linker error.

I hope this explanation was a bit clearer than the first.

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! ]