member pointers not constant expressions?

Discussion in 'C++' started by Noah Roberts, May 13, 2010.

  1. Noah Roberts

    Noah Roberts Guest

    Is a pointer to a member not a constant expression? I can use it as a
    template argument but I can't compare it to 0 in one:

    template < typename CONT, typename TYPE, TYPE (CONT::*fun)() const >
    struct test_meta
    {
    enum { has_fun = fun ? true:false };
    };

    struct test
    {
    int testing() const { return 5; }
    };


    typedef test_meta<test, int, &test::testing> try1;
    typedef test_meta<test, int, 0> try2;

    int main()
    {
    try1 t1;
    try2 t2;
    }


    VC++ 2010 vomits that up saying that a constant expression is expected
    at the read_only definition.

    I also had trouble specializing a different template (a metafunction)
    for a similar type. I can match a type with member variable pointers
    but not one with member function pointers.

    Can anyone clarify if this is so or if this compiler is busted?

    --
    http://crazyeddiecpp.blogspot.com/
     
    Noah Roberts, May 13, 2010
    #1
    1. Advertising

  2. According to my understanding there are a few problems with what you are
    trying to do below.

    Noah Roberts <> writes:

    > Is a pointer to a member not a constant expression? I can use it as a
    > template argument but I can't compare it to 0 in one:
    >
    > template < typename CONT, typename TYPE, TYPE (CONT::*fun)() const >
    > struct test_meta
    > {
    > enum { has_fun = fun ? true:false };
    > };


    I have not attempted to compile your code with VC, but the error message
    relating to requiring a constant expression is probably occurring here.
    As I understand it, an enumerator value must be a compile-time constant
    expression, and so cannot be assigned from the result of an evaluation
    using op?: which requires a runtime evaluation. See [expr.const]
    §5.19/1.

    > struct test
    > {
    > int testing() const { return 5; }
    > };
    >
    >
    > typedef test_meta<test, int, &test::testing> try1;
    > typedef test_meta<test, int, 0> try2;


    There is also a problem here since, for this to work, it would be
    required, in the case of try2 above, for your third template argument to
    undergo a null pointer to member conversion. However, this is not
    permitted according to §14.3.2/5:

    "The following conversions are performed on each expression used as a
    non-type template-argument. If a non-type template-argument cannot
    be converted to the type of the corresponding template-parameter then
    the program is ill-formed.

    - // ...

    - "For a non-type template-parameter of type pointer to member
    function, no conversions apply."

    > int main()
    > {
    > try1 t1;
    > try2 t2;
    > }
    >
    >
    > VC++ 2010 vomits that up saying that a constant expression is expected
    > at the read_only definition.
    >
    > I also had trouble specializing a different template (a metafunction)
    > for a similar type. I can match a type with member variable pointers
    > but not one with member function pointers.
    >
    > Can anyone clarify if this is so or if this compiler is busted?


    Regards

    Paul Bibbings
     
    Paul Bibbings, May 13, 2010
    #2
    1. Advertising

  3. Noah Roberts

    Noah Roberts Guest

    In article <>, says...
    >
    > According to my understanding there are a few problems with what you are
    > trying to do below.
    >
    > Noah Roberts <> writes:/1.
    >
    > > struct test
    > > {
    > > int testing() const { return 5; }
    > > };
    > >
    > >
    > > typedef test_meta<test, int, &test::testing> try1;
    > > typedef test_meta<test, int, 0> try2;

    >
    > There is also a problem here since, for this to work, it would be
    > required, in the case of try2 above, for your third template argument to
    > undergo a null pointer to member conversion. However, this is not
    > permitted according to §14.3.2/5:


    OK, damn. That's the source of all my ills here. VS compiles it and
    sort of works until I try to match the type in a specialization. I also
    tried nullptr (VS2010) and it didn't solve that issue. Do you know if
    nullptr is going to solve the problem when the standard comes out?

    --
    http://crazyeddiecpp.blogspot.com/
     
    Noah Roberts, May 14, 2010
    #3
  4. Noah Roberts <> writes:

    > In article <>, says...
    >>
    >> According to my understanding there are a few problems with what you are
    >> trying to do below.
    >>
    >> Noah Roberts <> writes:/1.
    >>
    >> > struct test
    >> > {
    >> > int testing() const { return 5; }
    >> > };
    >> >
    >> >
    >> > typedef test_meta<test, int, &test::testing> try1;
    >> > typedef test_meta<test, int, 0> try2;

    >>
    >> There is also a problem here since, for this to work, it would be
    >> required, in the case of try2 above, for your third template argument to
    >> undergo a null pointer to member conversion. However, this is not
    >> permitted according to §14.3.2/5:

    >
    > OK, damn. That's the source of all my ills here. VS compiles it and
    > sort of works until I try to match the type in a specialization. I also
    > tried nullptr (VS2010) and it didn't solve that issue. Do you know if
    > nullptr is going to solve the problem when the standard comes out?


    Where §14.3.2/5 in C++98 had:

    "For a non-type template-parameter of type pointer to member
    function, no conversions apply."

    The FCD for C++0x (n3092) has:

    "For a non-type template-parameter of type pointer to member
    function, if the template-argument is of type std::nullptr_t, the
    null member pointer conversion (4.11) is applied; otherwise, no
    conversions apply."

    So it seems, in relation to this specific part of your problem, you
    might just be in luck.

    Of course, there would still problems elsewhere in your code as it
    stands at the moment, specifically in that you would still be attempting
    to apply a run-time evaluation using op?: where a compile-time constant
    is needed.

    Regards

    Paul Bibbings
     
    Paul Bibbings, May 14, 2010
    #4
  5. Noah Roberts <> writes:

    > Is a pointer to a member not a constant expression? I can use it as a
    > template argument but I can't compare it to 0 in one:
    >
    > template < typename CONT, typename TYPE, TYPE (CONT::*fun)() const >
    > struct test_meta
    > {
    > enum { has_fun = fun ? true:false };
    > };
    >
    > struct test
    > {
    > int testing() const { return 5; }
    > };
    >
    >
    > typedef test_meta<test, int, &test::testing> try1;
    > typedef test_meta<test, int, 0> try2;
    >
    > int main()
    > {
    > try1 t1;
    > try2 t2;
    > }


    Just to jump back to your original post for a second, I have to admit
    that, aside from the details of your specific questions (snipped here),
    I'm not sure that I can fathom exactly what you are trying to do here.

    Are you, perhaps, wanting to set up a mechanism whereby you can
    determine whether or not a given type has a member function with a
    specific name and a specific return type (in the above example, taking
    no arguments)?

    One of the problems that I am having with this is the fact that,
    irrespective of whatever mechanism you envisage putting in place along
    the lines of what you are attempting, if `test' /doesn't/ have a member
    function called `testing' then you can't even get beyond forming the
    address (&test::testing) in the instantiation:

    test_meta<test, int, &test::testing>

    and if you can't get this far, then you can't invoke your mechanism to
    make any decision beyond what you must know already at this point, if
    that makes sense.

    In short, if test doesn't have a testing, you can't form &test::testing
    and so your mechanism is not invoked. On the other hand, if you *can*
    form &test::testing, then you already know the answer to what you are
    trying to deduce.

    It's probably a little more complex than that, but this is where I'm
    getting stuck at the moment trying to decipher what your aim is here.

    Regards

    Paul Bibbings
     
    Paul Bibbings, May 14, 2010
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fraser Ross
    Replies:
    4
    Views:
    1,077
    Fraser Ross
    Aug 14, 2004
  2. Replies:
    4
    Views:
    352
    Keith Thompson
    Dec 14, 2006
  3. n2xssvv g02gfr12930

    Smart pointers and member function pointers

    n2xssvv g02gfr12930, Nov 26, 2005, in forum: C++
    Replies:
    3
    Views:
    485
    n2xssvv g02gfr12930
    Nov 27, 2005
  4. Hamish
    Replies:
    3
    Views:
    599
    Alf P. Steinbach
    Jan 25, 2008
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    714
Loading...

Share This Page