C++ puzzle - how to get this to compile ?

Discussion in 'C++' started by OSS542, Dec 1, 2011.

  1. OSS542

    OSS542 Guest

    How might one go about getting something like the following example to
    compile successfully ?

    class cls2
    {
    friend void cls1::fun1();
    };
    class cls1
    {
    cls2 mbr1;
    public:
    void fun1();
    };
    OSS542, Dec 1, 2011
    #1
    1. Advertising

  2. OSS542 Wrote:

    > How might one go about getting something like the following
    > example to compile successfully ?
    >
    > class cls2
    > {
    > friend void cls1::fun1();
    > };
    > class cls1
    > {
    > cls2 mbr1;
    > public:
    > void fun1();
    > };


    As is, you can't.
    When processing cls2, the compiler does not yet know there is a cls1 with a
    member function fun1, so the friend declaration is ill-formed.
    And you can not move the definition of cls1 to before cl2 due to the member
    object mbr1.

    The following rewrites are possible to make it compile:
    <code 1>
    // Make the entire cls1 class a friend of cls2
    class cls1;
    class cls2
    {
    friend class cls1;
    };
    class cls1
    {
    cls2 mbr1;
    public:
    void fun1();
    };
    </code 1>

    <code 2>
    // Use a pointer for the member in cls1
    class cls2;
    class cls1
    {
    cls2* mbr1;
    public:
    void fun1();
    };
    class cls2
    {
    friend void cls1::fun1();
    };
    </code 2>

    Bart v Ingen Schenau
    Bart v Ingen Schenau, Dec 1, 2011
    #2
    1. Advertising

  3. On 12/1/2011 12:34 PM, Paavo Helde wrote:
    > OSS542<> wrote in news:1e5dd913-1403-42b9-bcc1-
    > :
    >
    >> How might one go about getting something like the following example to
    >> compile successfully ?
    >>
    >> class cls2
    >> {
    >> friend void cls1::fun1();
    >> };
    >> class cls1
    >> {
    >> cls2 mbr1;
    >> public:
    >> void fun1();
    >> };
    >>

    >
    > class cls2
    > {
    > // This function may only be called from class cls1!
    > void fun_for_cls1();
    > };
    > class cls1
    > {
    > cls2 mbr1;
    > public:
    > void fun1() {
    > mbr1.fun_for_cls1();


    'cls1::fun_for_cls1' is private in this context.

    > }
    >
    > };


    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 1, 2011
    #3
  4. On 12/1/2011 1:52 PM, Victor Bazarov wrote:
    > On 12/1/2011 12:34 PM, Paavo Helde wrote:
    >> OSS542<> wrote in news:1e5dd913-1403-42b9-bcc1-
    >> :
    >>
    >>> How might one go about getting something like the following example to
    >>> compile successfully ?
    >>>
    >>> class cls2
    >>> {
    >>> friend void cls1::fun1();
    >>> };
    >>> class cls1
    >>> {
    >>> cls2 mbr1;
    >>> public:
    >>> void fun1();
    >>> };
    >>>

    >>
    >> class cls2
    >> {
    >> // This function may only be called from class cls1!
    >> void fun_for_cls1();
    >> };
    >> class cls1
    >> {
    >> cls2 mbr1;
    >> public:
    >> void fun1() {
    >> mbr1.fun_for_cls1();

    >
    > 'cls1::fun_for_cls1' is private in this context.


    Sorry, should be 'cls2::fun_for_cls1'

    >
    >> }
    >>
    >> };

    >
    > V



    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 1, 2011
    #4
  5. OSS542 <> wrote:
    > class cls2
    > {
    > friend void cls1::fun1();
    > };
    > class cls1
    > {
    > cls2 mbr1;
    > public:
    > void fun1();
    > };


    In principle there's no technical reason why that couldn't be done. It's
    just a question of lacking syntax in the language.

    It would be useful if one could, somehow, declare member functions before
    the class definition is known. (If the class then fails to define the
    declared member function, a linker error would happen.) This can be done
    with namespaces, but not with classes.

    I'd say a syntax like this would be enough:

    class A;
    int A::foo(int, int);

    Anyone see any problem with that?
    Juha Nieminen, Dec 2, 2011
    #5
  6. On 12/2/2011 1:28 AM, Juha Nieminen wrote:
    > OSS542<> wrote:
    >> class cls2
    >> {
    >> friend void cls1::fun1();
    >> };
    >> class cls1
    >> {
    >> cls2 mbr1;
    >> public:
    >> void fun1();
    >> };

    >
    > In principle there's no technical reason why that couldn't be done. It's
    > just a question of lacking syntax in the language.
    >
    > It would be useful if one could, somehow, declare member functions before
    > the class definition is known. (If the class then fails to define the
    > declared member function, a linker error would happen.) This can be done
    > with namespaces, but not with classes.
    >
    > I'd say a syntax like this would be enough:
    >
    > class A;
    > int A::foo(int, int);
    >
    > Anyone see any problem with that?


    I think you're advocating forward-declaration of member functions. In
    that case the full qualification should be allowed for forward-declaring
    static, virtual, default, pure virtual and const members of the class.
    Basically there shouldn't be a problem if you want to write

    virtual int A::foo(int,int) const = 0;

    outside the class itself. However, currently the grammar does not allow
    the keyword 'virtual' to be used outside a class definition, and also
    defines a different meaning of the keyword 'static'.

    I don't see "any problem" except that the grammar needs to be made even
    more complicated to allow out-of-the-class-definition member declarations.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 2, 2011
    #6
  7. Victor Bazarov <> wrote:
    > I think you're advocating forward-declaration of member functions. In
    > that case the full qualification should be allowed for forward-declaring
    > static, virtual, default, pure virtual and const members of the class.
    > Basically there shouldn't be a problem if you want to write
    >
    > virtual int A::foo(int,int) const = 0;
    >
    > outside the class itself. However, currently the grammar does not allow
    > the keyword 'virtual' to be used outside a class definition, and also
    > defines a different meaning of the keyword 'static'.
    >
    > I don't see "any problem" except that the grammar needs to be made even
    > more complicated to allow out-of-the-class-definition member declarations.


    Perhaps if there was a way to do a kind of "partial declaration" of a
    class. In other words, you declare a class and some of its member functions
    (and other stuff, such as member types and variables), but it's still not
    a full class declaration (iow. you still can't instantiate the class
    based solely on this partial declaration).

    I don't have a good idea for a syntax for this. I get the feeling that
    the standardization committee abhors the addition of new reserved keywords
    (in order to, I suppose, minimize name collisions with existing code), and
    none of the existing reserved keywords that I can think of sound like a
    good fit for this. Perhaps the least horrible keyword I can think of
    would be 'namespace'. It could go something like this:

    namespace class A // partial declaration of A
    {
    public:
    virtual int foo(int, int) const = 0;
    int bar(int);
    int bar(int) const;
    class InnerClass;
    };

    Now it would be possible to refer to those member functions and types of
    the class A (and even call them using a reference/pointer of type A) before
    we have a full definition.
    Juha Nieminen, Dec 2, 2011
    #7
  8. OSS542

    OSS542 Guest

    My sincere thanks to Mr v Ingen Schenau and the rest of you for all
    your very kind assistance and a most interesting discussion.

    On Dec 1, 7:54 am, Bart v Ingen Schenau <> wrote:
    >
    > As is, you can't.
    > When processing cls2, the compiler does not yet know there is a cls1 witha
    > member function fun1, so the friend declaration is ill-formed.
    > And you can not move the definition of cls1 to before cl2 due to the member
    > object mbr1.
    >
    OSS542, Dec 6, 2011
    #8
    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. Nagaraj
    Replies:
    1
    Views:
    832
    Lionel B
    Mar 1, 2007
  2. timjowers
    Replies:
    7
    Views:
    4,302
    heyjude
    Feb 2, 2011
  3. Replies:
    1
    Views:
    431
    Cowboy \(Gregory A. Beamer\)
    Apr 11, 2008
  4. Carter
    Replies:
    2
    Views:
    488
    Carter
    Mar 4, 2009
  5. fAnSKyer
    Replies:
    2
    Views:
    513
    Alf P. Steinbach
    Jun 7, 2009
Loading...

Share This Page