pointer to member function as a template parameter

Discussion in 'C++' started by ank, Oct 30, 2006.

  1. ank

    ank Guest

    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


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    ank, Oct 30, 2006
    #1
    1. Advertising

  2. ank

    James Kanze Guest

    ank wrote:

    > 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.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    James Kanze, Oct 31, 2006
    #2
    1. Advertising

  3. ank

    ank Guest

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

    James Kanze wrote:
    >
    > 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.


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    ank, Nov 1, 2006
    #3
  4. ank

    L.Suresh Guest

    > 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.


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    L.Suresh, Nov 1, 2006
    #4
  5. ank

    James Kanze Guest

    ank wrote:
    > James Kanze wrote:


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


    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.)

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    James Kanze, Nov 1, 2006
    #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. Newsgroup - Ann
    Replies:
    5
    Views:
    656
    John Carson
    Jul 30, 2003
  2. Fraser Ross
    Replies:
    4
    Views:
    1,094
    Fraser Ross
    Aug 14, 2004
  3. Vijai Kalyan
    Replies:
    4
    Views:
    745
    Vijai Kalyan
    Nov 8, 2005
  4. Azdo
    Replies:
    2
    Views:
    453
  5. somenath
    Replies:
    2
    Views:
    178
    somenath
    Aug 29, 2013
Loading...

Share This Page