Topic: Static member function cast


Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/08/13
Raw View
Hans Aberg <haberg@REMOVE.matematik.su.se> writes:

> I only could not find a place where it was stated that the type is
> "int (*)()" and not say "int (static T::*)()".

>   Where is this specified?

[expr.unary.op]/2 and /5:

2 [...] For  a  qualified-id,
  if  the  member is a static member of type "T", the type of the result
  is plain "pointer to T."  If the member is a nonstatic member of class
  C  of  type T, the type of the result is "pointer to member of class C
  of type T." [...]

5 [...] [Note:  since  the
  context  might  determine whether the operand is a static or nonstatic
  member function, the context can also affect  whether  the  expression
  has type "pointer to function" or "pointer to member function."  ]

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/11
Raw View
In article <35CD6E0D.1A831FA2@see.my.sig>, Anatoli <anatoli@see.my.sig> wrote:
>Since the type of &B::f (where f is a static member) is `int (*)()',
>it is possible to use it wherever `int (*)()' can be used.
>I don't think it is necessary to state explicitly that &B::f
>and &f are compatible.  The type says it all.

  Sure, the type says it; I only could not find a place where it was
stated that the type is "int (*)()" and not say "int (static T::*)()".

  Where is this specified?

>I used to think that there *is* a deficiency re linkage:
>
>  extern "C" int foo();
>  int (*bar)() = foo;
>
>Current compilers swallow it.

  Some compilers might. However my old compiler (Symantec) produces the error:
    Error:   cannot implicitly convert
    from: int (*_cdecl)()
    to  : int (*"C++")()
So it distinguishes between them.

  Hans Aberg   * Anti-spam: Remove "REMOVE." from email address.
               * Email: Hans Aberg <haberg@REMOVE.member.ams.org>
               * Home Page: <http://www.matematik.su.se/~haberg/>
               * AMS member listing: <http://www.ams.org/cml/>


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW@my-dejanews.com
Date: 1998/08/07
Raw View
The standard almost never says anything about the implementation,
except the "As-If" rule. Besides, the implementation doesn't matter;
what matters is how you can and must write your code.

In the case of static member functions, you can call them just like
any non-member function, because that's exactly what they are.

> that casts, if the type signatures agree, are legal.

Casts have nothing to do with calling static functions. In your example,
the object supplies the address of a function to call, and the client
calls it. So long as the function has the correct signature, and is
either a non-member function or a static member function, the call is
legal and will produce the expected results.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/06
Raw View
In article <6qaf79$3am$1@nnrp1.dejanews.com>, AllanW@my-dejanews.com wrote:
>Member B::func can point to any static or global function that has
>the correct signature. Since f() has the correct signature, this is
>completely legal.
>
>The STL calls class objects like this a "functor."

  Thanks for the reply.

>> C++ does not allow template functions where the argument is not used to
>> identify the template class: One can then get around this by creating a
>
>You're supposed to use T somewhere in the definition of C.  Probably
>most compilers won't catch the omission, though.

  The template argument is used in the definition of the constructors,
where one may omit the tempalates at least for some constructors. In
addition, the function one wants to convert should have the template in
order for the example to make practical sense. For example (and the
purpose of this example is not that it should result in a frantic
discussion of programming techniques, but to illustrate a context were the
asked for C++ feature might be used),

    class Applicable {
    public:
        bool (*applicable)(Base*);
    };

    template<class T>
    class ApplicableClass : public Applicable {
    public:
        C() { Applicable::applicable = ApplicableClass<T>::applicable; }

        static bool applicable(Base* p)
        {   return dynamic_cast<T*>(p) != 0;   }
    };

Then one can check if a pointer is applicable dynamically by

    class Base { public: virtual ... };
    class Derived : public Base { public: };
    class DerivedToo : public Base { public: };

main() {
    Applicable b = ApplicableClass<Derived>();
    Base* p = new DerivedToo();

    if (b.applicable(p))
        ... // Do something.

  The advantage is that this is a check of dynamic objects, without the
class Applicable or its derived class is using dynamic allocation,
hopefully a little faster.

>You don't really need to get around this; if C is supposed to be a
>complete class, rather than just a code snippet, all you have to do is
>remove the words "template<class T>" to make C a non-template class.

  Of course not; I just tried to post an example which would give the
usage practical meaning.

  Hans Aberg   * Anti-spam: Remove "REMOVE." from email address.
               * Email: Hans Aberg <haberg@REMOVE.member.ams.org>
               * Home Page: <http://www.matematik.su.se/~haberg/>
               * AMS member listing: <http://www.ams.org/cml/>


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Anatoli <anatoli@see.my.sig>
Date: 1998/08/06
Raw View
Hans Aberg wrote:
>
>   Does the C++ standard guarantee that static member functions are
> implemented as global functions with a local name? That is, can a static
> member function pointer be converted into a global function pointer of the
> same (non-local) type, used, and then guaranteed to work?

Yes.  Don't have my ARM with me (no pun), but it says something
to the effect that pointers to static member functions are
normal function pointers (and pointers to static data members are
normal object pointers).  ISO didn't change it AFAIK.

> C++ does not allow template functions where the argument is not used to
> identify the template class: One can then get around this by creating a
> static member function and convert it to a global function pointer -- that
> is, if the C++ standard admits it. So by writing
>     B b = C<T>();
> one can use
>     char a = 'a';
>     int k = b.func(a);

C<T>::func(a) is also possible.
--
Regards
Anatoli (anatoli at ptc dot com) -- opinions aren't


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/06
Raw View
In article <9808060934.AA12917@news.ptc.com>, Anatoli <anatoli@see.my.sig>
wrote:
>..Don't have my ARM with me (no pun), but it says something
>to the effect that pointers to static member functions are
>normal function pointers (and pointers to static data members are
>normal object pointers).  ISO didn't change it AFAIK.

  I read that too, but it was not sufficient clear to me (I think it was
just in a commentary), hence the post:

  One would have expected a sentence to the effect that global and static
member functions are required by C++ to have the same implemnetation and
that casts, if the type signatures agree, are legal.

  One weakness of this C++ standard seems to be that it fails such
exactitude in several instances.

  Hans Aberg   * Anti-spam: Remove "REMOVE." from email address.
               * Email: Hans Aberg <haberg@REMOVE.member.ams.org>
               * Home Page: <http://www.matematik.su.se/~haberg/>
               * AMS member listing: <http://www.ams.org/cml/>


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/08
Raw View
>The standard almost never says anything about the implementation,
>except the "As-If" rule. Besides, the implementation doesn't matter;
>what matters is how you can and must write your code.
>
>In the case of static member functions, you can call them just like
>any non-member function, because that's exactly what they are.

  Here is a contradiction: First the statement that the standard does not
tell the implementation of static member functions, and the next statement
which says that the implementation is the same as of global functions.

>> that casts, if the type signatures agree, are legal.
>
>Casts have nothing to do with calling static functions. In your example,
>the object supplies the address of a function to call, and the client
>calls it. So long as the function has the correct signature, and is
>either a non-member function or a static member function, the call is
>legal and will produce the expected results.

  My suggestion was for a formulation that does not depend on knowledge of
implementation. Clearly, if
    class A {
    public:
        static int f(char);
    };
    int g(char);
then the types of f and g are different in the sense that one must somehow
define a conversion rule between them (no matter how this rule is
expressed).

  Hans Aberg   * Anti-spam: Remove "REMOVE." from email address.
               * Email: Hans Aberg <haberg@REMOVE.member.ams.org>
               * Home Page: <http://www.matematik.su.se/~haberg/>
               * AMS member listing: <http://www.ams.org/cml/>


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Anatoli <anatoli@see.my.sig>
Date: 1998/08/09
Raw View
Hans Aberg wrote:
[snip]
>   One would have expected a sentence to the effect that global and static
> member functions are required by C++ to have the same implemnetation and
> that casts, if the type signatures agree, are legal.
>
>   One weakness of this C++ standard seems to be that it fails such
> exactitude in several instances.

I don't think the Standard is deficient in this regard.
Since the type of &B::f (where f is a static member) is `int (*)()',
it is possible to use it wherever `int (*)()' can be used.
I don't think it is necessary to state explicitly that &B::f
and &f are compatible.  The type says it all.

I used to think that there *is* a deficiency re linkage:

  extern "C" int foo();
  int (*bar)() = foo;

Current compilers swallow it.  The standard, however, mandates
that the type of `foo' is `extern "C" int (*)()', not just
`int (*)()', and thus the compilers are deficient, not
the Standard.

--
Regards
Anatoli (anatoli at ptc dot com) -- opinions aren't


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/05
Raw View
  Does the C++ standard guarantee that static member functions are
implemented as global functions with a local name? That is, can a static
member function pointer be converted into a global function pointer of the
same (non-local) type, used, and then guaranteed to work?

  For example, write

    class B {
    public:
        int (*func)(char);
    };

    template<class T>
    class C : public B {
    public:
        C() { func = (int (*)(char))(f); }

        static int f(char) { ... }
    };

C++ does not allow template functions where the argument is not used to
identify the template class: One can then get around this by creating a
static member function and convert it to a global function pointer -- that
is, if the C++ standard admits it. So by writing
    B b = C<T>();
one can use
    char a = 'a';
    int k = b.func(a);

  Is this legal?

  Hans Aberg   * Anti-spam: Remove "REMOVE." from email address.
               * Email: Hans Aberg <mailto:haberg@member.ams.org>
               * Home Page: <http://www.matematik.su.se/~haberg/>
               * AMS member listing: <http://www.ams.org/cml/>


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW@my-dejanews.com
Date: 1998/08/05
Raw View
In article <haberg-0508981322390001@sl117.modempool.kth.se>,
  haberg@REMOVE.matematik.su.se (Hans Aberg) wrote:
>   Does the C++ standard guarantee that static member functions are
> implemented as global functions with a local name? That is, can a static
> member function pointer be converted into a global function pointer of the
> same (non-local) type, used, and then guaranteed to work?
>
>   For example, write
>
>     class B {
>     public:
>         int (*func)(char);
>     };
>
>     template<class T>
>     class C : public B {
>     public:
>         C() { func = (int (*)(char))(f); }
>
>         static int f(char) { ... }
>     };

Member B::func can point to any static or global function that has
the correct signature. Since f() has the correct signature, this is
completely legal.

The STL calls class objects like this a "functor."

> C++ does not allow template functions where the argument is not used to
> identify the template class: One can then get around this by creating a

You're supposed to use T somewhere in the definition of C.  Probably
most compilers won't catch the omission, though.

You don't really need to get around this; if C is supposed to be a
complete class, rather than just a code snippet, all you have to do is
remove the words "template<class T>" to make C a non-template class.

> static member function and convert it to a global function pointer -- that
> is, if the C++ standard admits it. So by writing
>     B b = C<T>();
> one can use
>     char a = 'a';
>     int k = b.func(a);
>
>   Is this legal?

Absolutely, although I repeat that C doesn't have to be a template.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]