non-constant reference

Discussion in 'C++' started by ma740988, Jul 19, 2005.

  1. ma740988

    ma740988 Guest

    Consider the source snippet.

    class foo_base
    {};

    template <typename T>
    class foo : public foo_base
    {
    public:
    typedef void (T::*F)();
    foo( T& t, F f) : t_(&t), f_(f) {}
    void operator()() const
    {
    (t_->*f_)();
    }
    private:
    T* t_;
    F f_;
    };

    template <class T>
    std::auto_ptr<foo_base> new_cb(T& t, void (T::*f)())
    {
    return std::auto_ptr<foo_base>(new foo<T>(t, f));
    }

    ---------
    class my_class {
    static std::auto_ptr<foo_base> test;
    public:
    template <typename T>
    my_class ( T& t, void (T::*f)()) {
    test = new_cb(t, f); /// 2
    }
    };
    ---------

    The line indicated by the number '2' works on the .NET 03 compiler but
    gcc complains about initilization of non-constant reference.

    C:\SW\MJT\Test\test.h:200: initialization of non-const reference
    type `class auto_ptr<foo_base> &'
    C:\SW\MJT\Test\test.h:200: from rvalue of type `auto_ptr<foo_base>'

    'long winded directory deleted'
    include\g++-3\memory:40: in passing argument 1 of
    `auto_ptr<foo_base>::eek:perator =(auto_ptr<foo_base> &)'


    Not sure if i follow the error and what the solution is. Thanks in
    advance.
     
    ma740988, Jul 19, 2005
    #1
    1. Advertisements

  2. Not enough information. How do you use 'my_class'? If I add

    std::auto_ptr<foo_base> my_class::test;

    struct fubar {
    void bar() {}
    };

    int main() {
    fubar f;
    my_class m(f, &fubar::bar);
    }

    to the end of your code, it compiles fine with Comeau online (provided
    Provide _complete_ code.

    V
     
    Victor Bazarov, Jul 19, 2005
    #2
    1. Advertisements

  3. Compiles for me with GCC 3.3.5 20050117 (prerelease) (SUSE Linux)

    <shrug>
     
    Steven T. Hatton, Jul 19, 2005
    #3
  4. But the template is not invoked (so you don't see the problem).
     
    Gianni Mariani, Jul 19, 2005
    #4
  5. What do you know that we don't?
     
    Victor Bazarov, Jul 19, 2005
    #5
  6. The line marked "/// 2" is within a template function that is never
    called. Hence the problem that the poster alludes to will not be
    identified by the compiler because the template is never instantiated.

    Hence, your response is correct, the code is incomplete.

    Apart from that, there are probably many things that I know that
    everyone else does not know.

    G
     
    Gianni Mariani, Jul 19, 2005
    #6
  7. ma740988

    ma740988 Guest

    Greetings Victor,

    | Provide _complete_ code.

    Makes no sense.. Will do
     
    ma740988, Jul 19, 2005
    #7
  8. ma740988

    ma740988 Guest

    Greetings Victor,

    | Provide _complete_ code.

    I'm obviously doing something wrong.. Will do
     
    ma740988, Jul 19, 2005
    #8
  9. ma740988

    ma740988 Guest

    -------------- sndr_exec.h --------------
    #ifndef SNDR_EXEC_H
    #define SNDR_EXEC_H

    # include "sl_comm.h"
    # include "com_header.h"

    class sndr_exec
    {
    private:
    Base *sndr_dy4;
    slDev* pslDevice_;
    public:
    sndr_exec();
    ~sndr_exec();
    void test_func();
    void my_user_callback(slDev *pslDevice_,
    unsigned int door_bell);
    };

    #endif // #ifndef sndr_exec

    -------------- sndr_exec.cpp --------------

    # include "sndr_exec.h"
    std::auto_ptr<test_base> Base::user_cb_func;
    sndr_exec::sndr_exec()
    : sndr_dy4(0)
    , pslDevice_(0)
    {
    sndr_dy4 = new(std::nothrow) Derived (
    *this,
    &sndr_exec::my_user_callback
    );
    if (!sndr_dy4)
    return;
    }

    sndr_exec::~sndr_exec() {}

    void sndr_exec::my_user_callback(
    slDev *pslDevice_,
    unsigned int door_bell)
    {
    std::cout << " this works YEAH " << std::endl;
    std::cout << " door_bell " << door_bell << std::endl;
    }
    void sndr_exec::test_func()
    {
    sndr_dy4->sl_callback_func(pslDevice_, 99);
    }


    -------------- sl_comm.h --------------
    #ifndef SL_COMM_H
    #define SL_COMM_H
    # include "com_header.h"

    struct slDev
    {
    unsigned int slFabricId;
    unsigned int slLinkId;
    unsigned int slBridgeId;
    void *arubaDev;
    void *instance;
    unsigned int pciIntAVector;
    };

    class test_base
    {
    public:
    virtual void operator()(slDev *pslDevice_,
    unsigned int bell_val) const {};
    virtual ~test_base() = 0;
    };

    inline test_base::~test_base() {}

    template <typename T>
    class cb : public test_base
    {
    public:
    typedef void (T::*F)(slDev *pslDevice_,
    unsigned int bell_val);
    cb( T& t, F f) : t_(&t), f_(f) {}
    void operator()(slDev *pslDevice_, unsigned int bell_val) const
    {
    (t_->*f_)(pslDevice_, bell_val);
    }
    private:
    T* t_;
    F f_;
    };

    template <typename T>
    cb<T> make_callback (
    T& t,
    void (T::*f)(slDev *pslDevice_,
    unsigned int bell_val)
    )
    {
    return cb<T>(t, f);
    }

    template <class T>
    std::auto_ptr<test_base> new_cb(
    T& t,
    void (T::*f)(slDev *pslDevice_,
    unsigned int bell_val)
    )
    {
    return std::auto_ptr<test_base>(new cb<T>(t, f));
    }

    class Base {
    private:
    static std::auto_ptr<test_base> user_cb_func;
    protected:

    template <typename T>
    Base(
    T& t,
    void (T::*f)(slDev *pslDevice_,
    unsigned int bell_val))
    {
    user_cb_func = new_cb(t, f); // COMPLAINS
    ABOUT THIS >>>>>
    }

    public:
    static void sl_callback_func(
    slDev *pslDevice_,
    unsigned int bell_val
    )
    {
    test_base& cb = *user_cb_func;
    cb(&pslDevice_, bell_val);
    }
    virtual ~Base()
    {}
    };

    class Derived : public Base {
    private:
    public:
    template <typename T>
    Derived(
    T& t,
    void (T::*f)(slDev *pslDevice_,
    unsigned int bell_val) )
    : Base(t, f)
    {}

    ~Derived()
    {}
    };

    #endif

    -------------- com_header.h --------------
    #ifndef COMM_HEADER
    #define COMM_HEADER

    // Standard C++
    # include <cstdio>
    # include <iostream>
    # include <iomanip>
    # include <stdlib.h>
    # include <string>
    # include <sstream>
    # include <stdexcept>
    # include <string>
    # include <memory>
    # include <functional>
    # include <algorithm>
    # include <iomanip>
    # include <numeric>
    # include <vector>
    # include <list>
    # include <map>
    # include <ctime>
    # include <bitset>
    # include <typeinfo>

    #endif // com_header.h

    -------------- main_test.cpp --------------
    #include "sndr_exec.h"

    sndr_exec* sndr_exec_(0);

    int main()
    {
    sndr_exec_ = new (std::nothrow) sndr_exec();
    sndr_exec_->test_func();
    delete sndr_exec;
    }


    The end result - gcc 2.96 complains about the line marked 'complains ..
    above'.
    Thanks again...
     
    ma740988, Jul 19, 2005
    #9
  10. I simply put it all in one file and fixed a couple of compile errors. I
    really don't like doing that, but here you go, this compiles. No, I did
    not try to run it.

    I am not trying to judge it (and don't ask me to), but next time don't
    post things that have to be put in separate files to be compiled. If it's
    a language problem you have, spend some effort reducing your code to the
    point where it's all in one module and exhibits the same error.
    --------------------------------------------------
    # include <cstdio>
    # include <iostream>
    # include <iomanip>
    # include <stdlib.h>
    # include <string>
    # include <sstream>
    # include <stdexcept>
    # include <string>
    # include <memory>
    # include <functional>
    # include <algorithm>
    # include <iomanip>
    # include <numeric>
    # include <vector>
    # include <list>
    # include <map>
    # include <ctime>
    # include <bitset>
    # include <typeinfo>

    struct slDev
    {
    unsigned int slFabricId;
    unsigned int slLinkId;
    unsigned int slBridgeId;
    void *arubaDev;
    void *instance;
    unsigned int pciIntAVector;
    };

    class test_base
    {
    public:
    virtual void operator()(slDev *pslDevice_, unsigned int bell_val)
    const {}
    virtual ~test_base() = 0;
    };

    inline test_base::~test_base() {}

    template<typename T> class cb : public test_base
    {
    public:
    typedef void (T::*F)(slDev *pslDevice_, unsigned int bell_val);

    cb(T& t, F f) : t_(&t), f_(f) {}

    void operator()(slDev *pslDevice_, unsigned int bell_val) const
    {
    (t_->*f_)(pslDevice_, bell_val);
    }

    private:
    T* t_;
    F f_;
    };

    template<typename T> cb<T> make_callback(T& t, void (T::*f)(slDev
    *pslDevice_, unsigned int bell_val))
    {
    return cb<T>(t, f);
    }

    template<class T>
    std::auto_ptr<test_base> new_cb(T& t, void (T::*f)(slDev *pslDevice_,
    unsigned int bell_val))
    {
    return std::auto_ptr<test_base>(new cb<T>(t, f));
    }

    class Base {
    private:
    static std::auto_ptr<test_base> user_cb_func;
    protected:

    template<typename T> Base( T& t, void (T::*f)(slDev *pslDevice_,
    unsigned int bell_val))
    {
    user_cb_func = new_cb(t, f); // COMPLAINS ABOUT THIS >>>>>
    }

    public:
    static void sl_callback_func(slDev *pslDevice_, unsigned int bell_val)
    {
    test_base& cb = *user_cb_func;
    cb(pslDevice_, bell_val);
    }

    virtual ~Base() {}
    };

    class Derived : public Base {
    private:
    public:
    template<typename T> Derived(T& t, void (T::*f)(slDev *pslDevice_,
    unsigned int bell_val))
    : Base(t, f)
    {}
    };


    class sndr_exec
    {
    private:
    Base *sndr_dy4;
    slDev* pslDevice_;
    public:
    sndr_exec();
    ~sndr_exec();
    void test_func();
    void my_user_callback(slDev *pslDevice_, unsigned int door_bell);
    };

    std::auto_ptr<test_base> Base::user_cb_func;

    sndr_exec::sndr_exec()
    : sndr_dy4(new (std::nothrow) Derived (*this, &sndr_exec::my_user_callback))
    , pslDevice_(0)
    {
    }

    sndr_exec::~sndr_exec() {}

    void sndr_exec::my_user_callback(slDev *pslDevice_, unsigned int door_bell)
    {
    std::cout << " this works YEAH " << std::endl;
    std::cout << " door_bell " << door_bell << std::endl;
    }

    void sndr_exec::test_func()
    {
    sndr_dy4->sl_callback_func(pslDevice_, 99);
    }

    sndr_exec *sndr_exec_ = 0;

    int main()
    {
    sndr_exec_ = new (std::nothrow) sndr_exec();
    sndr_exec_->test_func();
    delete sndr_exec_;
    }
     
    Victor Bazarov, Jul 19, 2005
    #10
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.