g++ "no matching function to call" using a template

Discussion in 'C++' started by Vaca Louca, Apr 27, 2005.

  1. Vaca Louca

    Vaca Louca Guest

    Hello,

    My setup: Debian sarge on dual Pentium 4. g++ 3.3.5-3.
    (the other system is Windows XP with MS Visual Studio .NET 2003)

    I have an auto_array<T> template (based on a template taken from the
    Corona
    project hosted at SourceForge) which basically wants to implement
    std::auto_ptr<T>
    semantics for an array.

    It used to compile and run the test program I wrote for it but suddenly
    it stopped
    compiling and I have no idea what did I do wrong (or change at all).

    On MS Visual Studio .NET 2003 the sample test program below (which I
    clipped
    down to demo the problem) compiles and runs find.

    Here is the sample program:

    #include <cstddef>
    #include <cstring>

    template<typename T>
    class auto_array
    {
    public:
    explicit auto_array (T* initial = 0) : array(initial) { }
    auto_array(auto_array<T>& other) : array(other.release()) { }
    ~auto_array() { delete[] array; }
    T* get() const { return array; }
    T* release() { T* old = array; array = 0; return old; }
    void reset(T* a = 0)
    {
    if (a != array) { delete[] array; array = a; }
    }
    void reset(auto_array<T>& a)
    {
    if (this != &a) { delete[] array; array = a.release(); }
    }
    auto_array<T> &operator= (T* a) { reset(a); return *this; }
    auto_array<T> &operator= (auto_array<T>& a)
    {
    reset(a.release()); return *this;
    }
    private:
    T* array;
    };

    auto_array<char> f(auto_array<char>& input) { return input; }

    int main(int argc, char* argv[])
    {
    auto_array<char> a,b,c;
    c.reset(a);
    b = c;
    // next two lines causes the errors
    c.reset(f(b));
    b = f(b);
    }

    The lines which cause the errors are the last two in main().

    Could someone please tell where is my mistake? I can't find it myself
    from digging the net or reading the books.

    Thanks,

    --Amos
    Vaca Louca, Apr 27, 2005
    #1
    1. Advertising

  2. "Vaca Louca" <> wrote in message
    news:...
    | Hello,
    |
    | My setup: Debian sarge on dual Pentium 4. g++ 3.3.5-3.
    | (the other system is Windows XP with MS Visual Studio .NET 2003)
    |
    | I have an auto_array<T> template (based on a template taken from the
    | Corona
    | project hosted at SourceForge) which basically wants to implement
    | std::auto_ptr<T>
    | semantics for an array.
    |
    | It used to compile and run the test program I wrote for it but suddenly
    | it stopped
    | compiling and I have no idea what did I do wrong (or change at all).

    [snip]

    I'm not sure whay you need this function, but instead of it...

    | auto_array<char> f(auto_array<char>& input) { return input; }

    [snip]

    ....change it to us a reference, and possibly even make it
    a template function as well:

    template<typename T>
    auto_array<T>& f( auto_array<T>& input )
    {
    return input;
    }

    Cheers,
    Chris Val
    Chris \( Val \), Apr 27, 2005
    #2
    1. Advertising

  3. Vaca Louca

    Vaca Louca Guest

    This function is used to test the function parameter passing and
    return of a local instance of auto_array<T>, and to make sure the value
    is copied correctly (and ownership is given up correctly).

    Actually, the original test function is:

    auto_array<char> f(auto_array<char>& input)
    {
    auto_array<char> local(input);
    return local;
    }

    Since the function returns a local variable it can't return a
    reference,
    but must use pass-byt-value.
    I just shortened the code as much as possible while still trying to
    demonstrate the problem.

    Thanks,

    --A
    Vaca Louca, Apr 28, 2005
    #3
  4. Vaca Louca

    Vaca Louca Guest

    Replying to myself (but maybe of benefit to others):

    Apparently, the function return value (the one being return by f()
    in my example) is considered "const", and therefore the operator=
    and the copy constructor were not considered as candidates which
    will accept this as an argument.
    Once I made them accept const parameters (and override the
    const using const_cast<> in order to actually reset the parameter's
    values)the program passed compilation.

    Here is the fixed program:

    template<typename T>
    class auto_array
    {
    public:
    explicit auto_array (T* initial = 0) : array(initial) { }
    auto_array(const auto_array<T>& a) : array(a.array)
    {
    if (this != &a)
    {
    const_cast<auto_array<T>*>(&a)->array = 0;
    }
    }
    ~auto_array() { delete[] array; }
    T* get() const { return array; }
    T* release() { T* old = array; array = 0; return old; }
    void reset(T* a = 0)
    {
    if (a != array) { delete[] array; array = a; }
    }
    void reset(const auto_array<T>& a)
    {
    if (array != a.array) {
    delete[] array;
    array = const_cast<auto_array<T>*>(&a)->release();
    }
    }
    auto_array<T> &operator= (T* a) { reset(a); return *this; }
    auto_array<T>& operator= (const auto_array<T>& a)
    {
    reset(const_cast<auto_array<T>*>(&a)->release()); return *this;
    }
    private:
    T* array;
    };

    auto_array<char> f(auto_array<char>& input) { return input; }

    int main(int argc, char* argv[])
    {
    auto_array<char> a,b,c;
    b.reset(a);
    c = b;
    // next lines used to cause the errors
    c.reset(f(b)); // simple reset
    c = f(b); // operator=
    auto_array<char> d(f(c)); // copy constructor
    }

    I only wonder if people can comment whether this looks to them
    as a good code. I'm a bit uneasy with all this const overriding
    (I think I should be worried at the design level - laying to the
    template's users about the constness of their objects).

    Thanks,

    --Amos
    Vaca Louca, Apr 28, 2005
    #4
  5. "Vaca Louca" <> wrote in message
    news:...
    | This function is used to test the function parameter passing and
    | return of a local instance of auto_array<T>, and to make sure the value
    | is copied correctly (and ownership is given up correctly).
    |
    | Actually, the original test function is:
    |
    | auto_array<char> f(auto_array<char>& input)
    | {
    | auto_array<char> local(input);
    | return local;
    | }
    |
    | Since the function returns a local variable it can't return a
    | reference, but must use pass-byt-value.

    True, but you failed to mention that :)

    | I just shortened the code as much as possible while still trying to
    | demonstrate the problem.

    Why not make the local instance 'static' ?

    auto_array<char>& f( auto_array<char>& input )
    {
    static auto_array<char> local( input );
    return local;
    }

    Then you can return by reference, and you do not need
    to go breaking things with const_cast as you have in
    your other post :)

    Btw, where do you allocate memory ?

    Cheers,
    Chris Val
    Chris \( Val \), Apr 28, 2005
    #5
  6. Vaca Louca

    Samee Zahur Guest

    I found a rather easy hack into your problem ... just add this line as
    a public member function:

    operator auto_array<T>&(){return *this;}

    It works with no complaints whatsoever!! (at least for gcc)

    Hold it! I still haven't got a clue as to what's happenning here. When
    returning an object by value, we do need a copy constructor, don't we?
    But array_ptr hasn't got one! It even works if I declare a copy-ctor
    myself and keep it in the *private* section! After experimenting a
    little with this myself, I'm beginning to suspect that the move-ctor
    symantecs have already been implemented in gcc (or I have been living
    in the stone age!)

    And as for the "no matching function" problem, the thing is gcc is a
    little lazy when it comes to matching up template parameters - a ctor
    needs a parameter of const T*, and it complains when it sees a call
    passed with a simple T* - it doesn't see the match without a partial
    specialization or something.

    > Apparently, the function return value (the one being return by f()
    > in my example) is considered "const",


    I wouldn't agree - you might want to look up one of my recent threads
    and what others had to say about it:

    http://groups-beta.google.com/group/comp.lang.c /browse_thread/thread/532943e5798f58db



    Samee
    Samee Zahur, Apr 30, 2005
    #6
  7. Vaca Louca

    Vaca Louca Guest

    I'm not sure what's happens with your operator overload either.

    I assume by "array_ptr" you mean "auto_array"? It does have
    a copy constructor.

    As far as I know the language, a "const T" should accept a plain
    "T", though not the toher way around.

    I see the thread you are reffering to. Don't know what to say about it.

    Thanks,

    --Amos
    Vaca Louca, May 4, 2005
    #7
  8. Vaca Louca

    Vaca Louca Guest

    STATIC??
    It's not thread-safe to begin with, and I need to allocate variable
    array size on top of this.
    Memory allocation is done with "new char[buffer_size]" and is
    used here just because Visual C++ 2003 .NET still doesn't
    support local arrays with variable size, e.g.:

    #ifdef _MSC_VER
    auto_array<char> auto_key_buffer(new char[key_buffer_size]);
    char *key_buffer(auto_key_buffer.get());
    #else
    char key_buffer[key_buffer_size];
    #endif

    I need this because I don't want to leak memory in case of an exception
    or other unplanned function return.

    Cheers,

    --Amos
    Vaca Louca, May 4, 2005
    #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. Chris Theis
    Replies:
    2
    Views:
    447
    Chris Theis
    Jul 24, 2003
  2. tom_usenet
    Replies:
    0
    Views:
    516
    tom_usenet
    Jul 24, 2003
  3. Replies:
    1
    Views:
    2,075
    Gianni Mariani
    Jun 8, 2007
  4. Peng Yu
    Replies:
    3
    Views:
    752
    Thomas J. Gritzan
    Oct 26, 2008
  5. nguillot
    Replies:
    5
    Views:
    511
Loading...

Share This Page