templates and friends

Discussion in 'C++' started by Kevin Christopher, Jul 1, 2003.

  1. I've got a pile of code that won't compile for me, and can't figure out
    why. I'm either making a template / friend / operator overloading
    mistake (most likely - & why I'm asking here), or I'm using something
    not supported by g++ 2.96 (less likely).

    The big picture: I'm writing a wrapper class template that is supposed
    to wrap around a primitive data type so that I can send myself
    notifications whenever some code changes that data type (i.e. read from
    or write to). My idea was a wrapper that overloads the operator=()
    function. Works great, except for assigning with operator=(int,
    wrapper) which doesn't compile. Demonstration code attached (somewhat
    long, but all the relevant functions are there). Demonstration code
    runs as is right now... there are three commented-out sections dealing
    with the one friend function that I need to get compiling.

    Can anyone tell me what I'm doing wrong? The g++ error message is:
    operator=(base_t&, const notify_wrapper<base_t>)&) must be a
    nonstatic member function
    and I don't feel that it has to be - this is an external helper function
    for when I want to do: (base_t) = wrapper<base_t>. And since base_t is
    a primitive type, I can't add this as a member function.

    (code follows as attachment)

    -Kevin


    #include <iostream>

    class wrapper_listener
    {
    public:
    virtual void written_to(void) {cout << "written" << endl;}
    virtual void read_from(void) {cout << "read" << endl;}
    };

    template <typename base_t>
    class notify_wrapper
    {
    public:
    notify_wrapper() {}
    ~notify_wrapper() {}

    public:
    operator base_t ();

    notify_wrapper<base_t>& operator=
    (const notify_wrapper<base_t>& rhs);

    notify_wrapper<base_t>& operator=
    (const base_t& rhs);

    /*
    friend
    void operator=<base_t>
    (base_t& lhs, const notify_wrapper<base_t>& rhs);
    */

    private:
    base_t base;

    public:
    static wrapper_listener* listener;
    };

    /*
    template <typename base_t>
    void operator=
    (base_t& lhs, const notify_wrapper<base_t>& rhs);
    */

    template <typename base_t>
    notify_wrapper<base_t>::eek:perator base_t
    ()
    {
    return this->base;
    }

    template <typename base_t>
    notify_wrapper<base_t>&
    notify_wrapper<base_t>::eek:perator=
    (const notify_wrapper<base_t>& rhs)
    {
    base = (base_t) rhs.base;
    if(rhs.listener) rhs.listener->read_from();
    if(listener) listener->written_to();
    }

    template <typename base_t>
    notify_wrapper<base_t>&
    notify_wrapper<base_t>::eek:perator=
    (const base_t& rhs)
    {
    base = rhs;
    if(listener) listener->written_to();
    return *this;
    }
    /*
    template <typename base_t>
    void //disallow future assignments!
    ::eek:perator=
    (base_t& lhs, const notify_wrapper<base_t>& rhs)
    {
    lhs = (base_t) rhs.base;
    if(listener) listener->read_from();
    }
    */

    wrapper_listener* notify_wrapper<int>::listener;

    int main()
    {
    int i;
    wrapper_listener wrapper;
    notify_wrapper<int> tester;
    notify_wrapper<int>::listener = &wrapper;
    tester = 5;
    i = tester;

    return 0;
    }
     
    Kevin Christopher, Jul 1, 2003
    #1
    1. Advertising

  2. Victor Bazarov wrote:
    > Please do not post attachments in this newsgroup. If you need
    > to post code, copy and paste it into the message. However,
    > before you do that, please, read the FAQ 5.8.

    Ironically enough, I managed to read the FAQ and distill out a sample
    file without seeing the no-attachments part. Foolish of me.

    Alas, here is the file, copy-and-pasted. I have beeen attempting to
    compile it with g++ 2.96, simply with "g++ test.cc"

    -Kevin
    =================================================
    #include <iostream>

    class wrapper_listener
    {
    public:
    virtual void written_to(void) {cout << "written" << endl;}
    virtual void read_from(void) {cout << "read" << endl;}
    };

    template <typename base_t>
    class notify_wrapper
    {
    public:
    notify_wrapper() {}
    ~notify_wrapper() {}

    public:
    operator base_t ();

    notify_wrapper<base_t>& operator=
    (const notify_wrapper<base_t>& rhs);

    notify_wrapper<base_t>& operator=
    (const base_t& rhs);

    /*
    friend
    void operator=<base_t>
    (base_t& lhs, const notify_wrapper<base_t>& rhs);
    */

    private:
    base_t base;

    public:
    static wrapper_listener* listener;
    };

    /*
    template <typename base_t>
    void operator=
    (base_t& lhs, const notify_wrapper<base_t>& rhs);
    */

    template <typename base_t>
    notify_wrapper<base_t>::eek:perator base_t
    ()
    {
    return this->base;
    }

    template <typename base_t>
    notify_wrapper<base_t>&
    notify_wrapper<base_t>::eek:perator=
    (const notify_wrapper<base_t>& rhs)
    {
    base = (base_t) rhs.base;
    if(rhs.listener) rhs.listener->read_from();
    if(listener) listener->written_to();
    }

    template <typename base_t>
    notify_wrapper<base_t>&
    notify_wrapper<base_t>::eek:perator=
    (const base_t& rhs)
    {
    base = rhs;
    if(listener) listener->written_to();
    return *this;
    }
    /*
    template <typename base_t>
    void //disallow future assignments!
    ::eek:perator=
    (base_t& lhs, const notify_wrapper<base_t>& rhs)
    {
    lhs = (base_t) rhs.base;
    if(listener) listener->read_from();
    }
    */

    wrapper_listener* notify_wrapper<int>::listener;

    int main()
    {
    int i;
    wrapper_listener wrapper;
    notify_wrapper<int> tester;
    notify_wrapper<int>::listener = &wrapper;
    tester = 5;
    i = tester;

    return 0;
    }
     
    Kevin Christopher, Jul 1, 2003
    #2
    1. Advertising

  3. "Kevin Christopher" <> wrote...
    > Victor Bazarov wrote:
    > > Please do not post attachments in this newsgroup. If you need
    > > to post code, copy and paste it into the message. However,
    > > before you do that, please, read the FAQ 5.8.

    > Ironically enough, I managed to read the FAQ and distill out a sample
    > file without seeing the no-attachments part. Foolish of me.
    >
    > Alas, here is the file, copy-and-pasted. I have beeen attempting to
    > compile it with g++ 2.96, simply with "g++ test.cc"


    (a) Having read the FAQ you still managed to follow the first
    6 key guidelines but for some reason decided to ignore #7,
    which IMHO is the most important. If you receive compiler
    diagnostic, what is it? I don't have your compiler, nor do
    I have your OS or anything else the compilation may depend
    on. So, I cannot answer your inquiry. Neither can many of
    other regulars here. Well, of course, I exaggerate a bit,
    but still...

    (b) Why are you using such an ancient compiler? Is there any
    legitimate reason for you not to upgrade to something at
    least a bit more Standard-compliant?

    (c) In your code, add "using namespace std;" after the first line
    (it may not help with g++ v2.96, but it will make your code
    closer to legal C++).

    (d) Add
    template<class T> wrapper_listener* notify_wrapper<T>::listener;
    before line 84.

    (e) Line 85 (former 84) should look like this:
    template wrapper_listener* notify_wrapper<int>::listener;

    That should do it.

    Victor
     
    Victor Bazarov, Jul 2, 2003
    #3
  4. Kevin Christopher

    tom_usenet Guest

    On Tue, 01 Jul 2003 15:29:24 -0700, Kevin Christopher
    <> wrote:

    > /*
    > friend
    > void operator=<base_t>
    > (base_t& lhs, const notify_wrapper<base_t>& rhs);
    > */


    operator= has to be a member function according to the C++ standard.
    You need:

    friend base_t& base_t::eek:perator=(const notify_wrapper<base_t>& rhs);

    Obviously, this won't work for built in types - you can't override the
    meaning of assignment for built ins, which is a reasonable
    restriction. You'll have to rethink your design.

    Tom
     
    tom_usenet, Jul 2, 2003
    #4
    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. Buster Copley
    Replies:
    5
    Views:
    562
    Gianni Mariani
    Jul 7, 2003
  2. JKop
    Replies:
    3
    Views:
    479
  3. Replies:
    2
    Views:
    604
  4. recover
    Replies:
    2
    Views:
    813
    recover
    Jul 25, 2006
  5. Replies:
    0
    Views:
    660
Loading...

Share This Page