member pointers not constant expressions?

N

Noah Roberts

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?
 
P

Paul Bibbings

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

Noah Roberts said:
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
 
N

Noah Roberts

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



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?
 
P

Paul Bibbings

Noah Roberts said:
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
 
P

Paul Bibbings

Noah Roberts said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top