Topic: Member Function pointer Template parameters


Author: Patrick Hoonhout <phoonhout@symantec.com>
Date: 1995/05/22
Raw View
>>Using Sun C++ 4.0, I was able to make a template definition using a pointer
>>to the function strlen.  I get an error, when I tried to make one using
>>pointer to member notation.
>
>A template parameter is allowed to be a pointer to an ordinary function, or a
>pointer to member, but not a pointer to member function. [14.8] The reason is
>that a pointer to a member function involves complicated runtime issues. It

Steve,

Pointers to Template member functions can be achieved.

// Typedef for FPTR to be a pointer to vehicle member function that takes
// 'Type* const' as an argument and returns a char*.
typedef char* (vehicle<Type>::*FPTR)(Type* const);

// get the address to 'GetVehicleModel' member function.
FPTR funcptr;
funcptr = &vehicle<Type>::GetVehicleModel;

// Call the member function.
char* VehicleModelName = (this->*funcptr)(VehicleName);


Patrick Hoonhout
Symantec Tech Support






Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/05/19
Raw View
In article <bgibbons-1705951531220001@bill-gibbons1.taligent.com>
bgibbons@taligent.com (Bill Gibbons) writes:

|> In article <KANZE.95May17111146@slsvhdt.lts.sel.alcatel.de>,
|> kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) wrote:

|> > What is not allowed is something like the following:
|> >
|> >         typedef double (X::*Pmf)( double ) ;
|> >         template< Pmf x > ...
|> >
|> > In this case, the compiler would be required to evaluate the value of
|> > a pointer to member function as a constant.  What Steve pointed out is
|> > that this is, in practice, not (always) possible.

|> That isn't my reading of the draft.  In section 14.8, in a discussion of
|> nontype template arguments, it reads:
    [...]

Sorry about that.  I was only commenting the posters misinterpretation
of Steve's remarks, and didn't bother to verify in the draft.  You're
right.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/05/16
Raw View
In article mrp@ritz.cec.wustl.edu, jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut) writes:
>Using Sun C++ 4.0, I was able to make a template definition using a pointer
>to the function strlen.  I get an error, when I tried to make one using
>pointer to member notation.

A template parameter is allowed to be a pointer to an ordinary function, or a
pointer to member, but not a pointer to member function. [14.8] The reason is
that a pointer to a member function involves complicated runtime issues. It
isn't clear what it means to instantiate a type based on run-time
properties. (A pointer to member function can point to a virtual function
with a covariant return type for example; it isn't so much a constant as
it is an algorithm for finding and calling a function.)

>The only thing that I saw in the WP is that
>you can't create a non-type template-parameter from a double [14.7].
>
>By the way...what's special about a double?

It isn't 'double' that's special; the restriction is on floating-point
types. Suppose you were allowed to write
 template< double d > class T { ... };
and then you instantiate
 T<1.0/3.0> t1;
 T<2.0/6.0> t2;
Are t1 and t2 the same type? It depends on how the compiler and machine do
floating-point arithmetic. (I'll refrain from making any Intel jokes.)

Technically, you not even assured that
 (1.0 + 2.0) == 3.0
Thus, you wouldn't get any dependable results from floating-point template
parameters.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/05/17
Raw View
In article <3pbovs$ces@gap.cco.caltech.edu>
blair@olympia.gps.caltech.edu (Blair Zajac) writes:

|> Steve Clamage (clamage@Eng.Sun.COM) wrote:
|> > A template parameter is allowed to be a pointer to an ordinary function, or a
|> > pointer to member, but not a pointer to member function. [14.8] The reason is
|> > that a pointer to a member function involves complicated runtime issues. It
|> > isn't clear what it means to instantiate a type based on run-time
|> > properties. (A pointer to member function can point to a virtual function
|> > with a covariant return type for example; it isn't so much a constant as
|> > it is an algorithm for finding and calling a function.)

|> If I understand this correctly, then you shouldn't be able to do the
|> following (which I now do with Sun C++ 4.0.1 and G++ 2.6.3).  I designed
|> a template function which minimizes a function (which happens to be a
|> member function) which takes a double and returns a double.  This function
|> comes in handy for a variety of different classes.  I wouldn't want to
|> derive these different classes from a common base class that offered the
|> minimization routine.

|> template<class T, class POINTER_TO_MEMBER_FUNCTION>
|> double Minimize(const T&                   ObjectRef
|>                 POINTER_TO_MEMBER_FUNCTION MemberFunctionPointer)
|> {
|>   // Some code to find the x that minimizes
|>   // (ObjectRef.*MemberFunctionPointer)(x)

|>   return x;
|> }

This should be OK.  You are instantiating the template on a type, not
on a pointer to member function.  The compiler can determine the type
(say `double (X::*)( double )') at compile time without any problem.

What is not allowed is something like the following:

 typedef double (X::*Pmf)( double ) ;
 template< Pmf x > ...

In this case, the compiler would be required to evaluate the value of
a pointer to member function as a constant.  What Steve pointed out is
that this is, in practice, not (always) possible.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: blair@olympia.gps.caltech.edu (Blair Zajac)
Date: 1995/05/17
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
> A template parameter is allowed to be a pointer to an ordinary function, or a
> pointer to member, but not a pointer to member function. [14.8] The reason is
> that a pointer to a member function involves complicated runtime issues. It
> isn't clear what it means to instantiate a type based on run-time
> properties. (A pointer to member function can point to a virtual function
> with a covariant return type for example; it isn't so much a constant as
> it is an algorithm for finding and calling a function.)

If I understand this correctly, then you shouldn't be able to do the
following (which I now do with Sun C++ 4.0.1 and G++ 2.6.3).  I designed
a template function which minimizes a function (which happens to be a
member function) which takes a double and returns a double.  This function
comes in handy for a variety of different classes.  I wouldn't want to
derive these different classes from a common base class that offered the
minimization routine.

template<class T, class POINTER_TO_MEMBER_FUNCTION>
double Minimize(const T&                   ObjectRef
                POINTER_TO_MEMBER_FUNCTION MemberFunctionPointer)
{
  // Some code to find the x that minimizes
  // (ObjectRef.*MemberFunctionPointer)(x)

  return x;
}

class Work {
public:
  double calc(const double) const { return ....; }
};

int main()
{
  Work w;
  cout << Minimize(w, Work::calc) << endl;
  return 0;
}

If this feature is going to disappear from the compilers I use, then I
guess I could write a static class function that takes a reference to
the class and x parameter and do the same calculation, but it would be
a hassle.

I haven't used this template function on any virtual classes or functions
however, so I don't know if the compilers can handle it.

Blair Zajac
--
Blair Zajac   Division of Geological and Planetary Sciences
blair@olympia.gps.caltech.edu California Institute of Technology
(818) 395-6932   252-21, Pasadena, CA 91125
--
Blair Zajac   Division of Geological and Planetary Sciences
blair@olympia.gps.caltech.edu California Institute of Technology
(818) 395-6932   252-21, Pasadena, CA 91125





Author: jhs@edg.com (John H. Spicer)
Date: 1995/05/17
Raw View
In article <3pb3rf$ami@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM writes:
>In article mrp@ritz.cec.wustl.edu, jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut) writes:
>>Using Sun C++ 4.0, I was able to make a template definition using a pointer
>>to the function strlen.  I get an error, when I tried to make one using
>>pointer to member notation.
>
>A template parameter is allowed to be a pointer to an ordinary function, or a
>pointer to member, but not a pointer to member function. [14.8] The reason is
>that a pointer to a member function involves complicated runtime issues. It
>isn't clear what it means to instantiate a type based on run-time
>properties. (A pointer to member function can point to a virtual function
>with a covariant return type for example; it isn't so much a constant as
>it is an algorithm for finding and calling a function.)
>

I'm afraid that this isn't quite right.

The WP says a nontype template parameter may be a pointer to member.
It does not restrict it to only a pointer to data member.

This is based on issue 6.17 from my template issues paper.  This
issue was approved at the Waterloo meeting (7/94) and clearly
includes both pointer to data and pointer to function types.

John Spicer
Edison Design Group






Author: bgibbons@taligent.com (Bill Gibbons)
Date: 1995/05/17
Raw View
In article <KANZE.95May17111146@slsvhdt.lts.sel.alcatel.de>,
kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) wrote:

> What is not allowed is something like the following:
>
>         typedef double (X::*Pmf)( double ) ;
>         template< Pmf x > ...
>
> In this case, the compiler would be required to evaluate the value of
> a pointer to member function as a constant.  What Steve pointed out is
> that this is, in practice, not (always) possible.

That isn't my reading of the draft.  In section 14.8, in a discussion of
nontype template arguments, it reads:

   A non-type non-reference template-argument shall be a constant-
   expression of non-floating type, the address of an object or a func
   tion with external linkage, or a non-overloaded pointer to member.
   ...
   A pointer to member shall be expressed as &X::m where X is a
   (possibly qualified) name of a class and m is the name of a
   nonstatic member of X.

In the context in which this sentence appears, there is no doubt that
the meaning is to allow pointer to member nontype template arguments.


The limitations on template nontype arguments are not limitations on
values, but rather on *identity*.

It must be possible to uniquely identify a particular instance by
associating a unique name or value with each template parameter.

Uniqueness of type parameters is guaranteed by only allowing types composed
from builtin types and from types with external linkage.

Uniqueness of non-address nontype parameters is guaranteed by only allowing
constants, and in particular only constants with values which are easily
uniquely identified when represented as text.  This rules out floating-point
constants.  (Since you can add extra digits to the text representation
of floating-point constants without changing the converted value, it's hard
to guarantee uniqueness.)

Uniqueness of address nontype parameters is guaranteed by only allowing
addresses of things with external linkage (similar rules apply to
references).

Since members have external linkage, pointers to members meet the needs
of uniqueness of address nontype parameters, and there is no reason to
exclude them.  The fact that they are not "addresses" in the conventional
sense is not important; it's the external linkage that counts.


The actual instantiation is performed by just substituting the value of
the template formal parameter wherever it's used in the template; this is
no harder with pointers to members than with any other nontype parameters.
It does *not* require constant values.

Since the draft clearly supports pointers to members as nontype arguments,
and there is no difficulty with the meaning or implementation, the fact
that some compilers do not support the feature just implies compiler
bugs.


The only problem I see here is that the restriction on overloaded
pointer to members is totally unnecessary.  After all, instantiation will
pick a particular function from the set of member functions; this is no
different with pointers to members than with pointers to ordinary functions.

--
Bill Gibbons
bgibbons@taligent.com