pointer to member function as a template parameter

A

ank

Hi,

I write simple class to transform member function into non member
function
(with some rearrangement of its parameter).

The code is:

template<class T_, int (T_::*mfn_)()>
class Mfn {
public:
static int fn(T_* pT) { return (pT->*mfn_)(); }
};

and then try it with some test class like this:

class Test {
private:
// note that this member function is private
int test()
{
std::cout << "Test::test()" << std::endl;
return 0;
}
};

Then Mfn is used like this:

Test t;
Mfn<Test, &Test::test>::fn(&t);

The question is: "What is the sensible behavior of this code?"
Possible answer is:
1. Fail to compile outside of class "Test" (if it is used inside Test,
it should be OK)
2. Undefined behavior

I have tested it and the code compiles cleanly for 1 compiler (I don't
know about other compiler)
but if I change the member function to static and change the template
parameter accordingly,
it obviously failed as I expected.

I expected the test code to fail outside class "Test"

I don't really know if the standard defined this case or not.

Regards,
Ekaphol
 
J

James Kanze

ank said:
I write simple class to transform member function into non
member function (with some rearrangement of its parameter).
The code is:
template<class T_, int (T_::*mfn_)()>
class Mfn {
public:
static int fn(T_* pT) { return (pT->*mfn_)(); }
};
and then try it with some test class like this:
class Test {
private:
// note that this member function is private
int test()
{
std::cout << "Test::test()" << std::endl;
return 0;
}
};
Then Mfn is used like this:
Test t;
Mfn<Test, &Test::test>::fn(&t);
The question is: "What is the sensible behavior of this code?"
Possible answer is:
1. Fail to compile outside of class "Test" (if it is used
inside Test, it should be OK)

I don't see where there can be any question about it. What is
private is the declaration. Outside of the class, any attempt
to use the declaration is illegal. How you are attempting to
use it is irrelevant.
 
A

ank

{ Please do not quote the signature and the banner. -mod }

James said:
I don't see where there can be any question about it. What is
private is the declaration. Outside of the class, any attempt
to use the declaration is illegal. How you are attempting to
use it is irrelevant.

Are you saying that according to the standard,
this code should not compile (of course, if use outside class Test),
right?

What if I use the code inside the class like this

class Test {
public:
int trySomething()
{
Test t;
Mfn<Test, &Test::test>::fn(&t);
}
private:
// note that this member function is private
int test()
{
std::cout << "Test::test()" << std::endl;
return 0;
}

};

&Test::test is accessible inside Test

Is this program well-formed?

I just want to know if the compiler should instantiate the template
with its parameter as a name that has been private in some class or not.
 
L

L.Suresh

Is this program well-formed?
Yes.
I just want to know if the compiler should instantiate the template
with its parameter as a name that has been private in some class or not.

it depends on where it is used. here, it has the accessibility to take
the address.
 
J

James Kanze

ank said:
James Kanze wrote:
Are you saying that according to the standard, this code
should not compile (of course, if use outside class Test),
right?

Maybe. It's an error which requires a diagnostic. A compiler
could issue a diagnostic, and then compile it anyway. Normally,
as a quality of implementation issue, I would be against this,
but if the compiler had allowed such code in its pre-standard
versions, it is quite reasonable for it to continue allowing it,
rather than breaking user code; in such cases, several compilers
emit a diagnostic along the lines of "anacronism", and still
compile the code.
What if I use the code inside the class like this
class Test {
public:
int trySomething()
{
Test t;
Mfn<Test, &Test::test>::fn(&t);
}
private:
// note that this member function is private
int test()
{
std::cout << "Test::test()" << std::endl;
return 0;
}

};
&Test::test is accessible inside Test
Is this program well-formed?
Sure.

I just want to know if the compiler should instantiate the
template with its parameter as a name that has been private in
some class or not.

The instantiation doesn't really use the name directly, and
access is never checked on the arguments of a template. You can
only trigger the instantiation of a class, however, in a context
where you can name the type. (It is possible, however, to
instantiate a function with a private type even outside of the
class, although I doubt that such cases occur very often in real
code.)
 

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,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top