Problem with Copy Constructor and overloaded assignment operator with templates

Discussion in 'C++' started by saxman, Jun 12, 2007.

  1. saxman

    saxman Guest

    Hi everyone,

    I'm writing a class that inherits from std::vector in order to add
    some additional functionality. I'm having a compiler problem, however,
    when I have a function that returns this class. I've drilled down and
    been able to create a very simple example of the problem. Here's my
    code:

    <code>
    #include <vector>
    #include <iostream>

    using std::vector;
    using std::cout;
    using std::endl;

    template <typename T>
    class B : public std::vector<T>
    {
    public:
    B(){ cout << "In B ctor" << endl; }

    B(B<T> &b) { cout << "In B copy ctor" << endl; }

    B<T>& operator=(const B<T> &b) { cout << "In B assign." << endl;
    return *this; }

    ~B(){ cout << "In B destructor" << endl; }

    };

    B<int> test()
    {
    B<int> returnVal;
    return returnVal;
    }

    int main()
    {
    B<int> b;
    b = test();
    return 0;
    }
    </code>

    I get the following error when compiling:
    test.cpp: In function `int main()':
    test.cpp:31: error: no matching function for call to
    `B<int>::B(B<int>)'
    test.cpp:14: note: candidates are: B<T>::B(B<T>&) [with T = int]

    Does anyone know of a solution?

    Some additional information: any of the following code in 'main'
    compiles fine:
    <code>
    B<int> b;
    B<int> b2 = b;
    return 0;
    </code>

    or

    <code>
    B<int> b;
    B<int> b2;
    b2 = b;
    return 0;
    </code>

    or

    <code>
    B<int> b;
    B<int> b2(b);
    return 0;
    </code>

    Any help would be greatly appreciated.
     
    saxman, Jun 12, 2007
    #1
    1. Advertising

  2. On 12 Juni, 16:08, saxman <> wrote:
    > Hi everyone,
    >
    > I'm writing a class that inherits from std::vector in order to add
    > some additional functionality. I'm having a compiler problem, however,
    > when I have a function that returns this class. I've drilled down and
    > been able to create a very simple example of the problem. Here's my
    > code:
    >
    > <code>
    > #include <vector>
    > #include <iostream>
    >
    > using std::vector;
    > using std::cout;
    > using std::endl;
    >
    > template <typename T>
    > class B : public std::vector<T>
    > {
    > public:
    > B(){ cout << "In B ctor" << endl; }
    >
    > B(B<T> &b) { cout << "In B copy ctor" << endl; }
    >
    > B<T>& operator=(const B<T> &b) { cout << "In B assign." << endl;
    > return *this; }
    >
    > ~B(){ cout << "In B destructor" << endl; }
    >
    > };
    >
    > B<int> test()
    > {
    > B<int> returnVal;
    > return returnVal;
    >
    > }
    >
    > int main()
    > {
    > B<int> b;
    > b = test();


    The problem is that the compiler converts this to a copy-constructor
    call like this 'B<int>(test())', however since your copy-constructor
    takes a reference as a parameter this can not compile (since a
    reference can not bind to the temporary returned by test()). To solve
    this simply change the copy-constructor to 'B(const B<T> &b)'. In
    general the parameters to copy-constructors should be const.

    --
    Erik Wikström
     
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Jun 12, 2007
    #2
    1. Advertising

  3. saxman

    saxman Guest

    On Jun 12, 10:16 am, Erik Wikström <> wrote:
    > On 12 Juni, 16:08, saxman <> wrote:
    >
    >
    >
    > > Hi everyone,

    >
    > > I'm writing a class that inherits from std::vector in order to add
    > > some additional functionality. I'm having a compiler problem, however,
    > > when I have a function that returns this class. I've drilled down and
    > > been able to create a very simple example of the problem. Here's my
    > > code:

    >
    > > <code>
    > > #include <vector>
    > > #include <iostream>

    >
    > > using std::vector;
    > > using std::cout;
    > > using std::endl;

    >
    > > template <typename T>
    > > class B : public std::vector<T>
    > > {
    > > public:
    > > B(){ cout << "In B ctor" << endl; }

    >
    > > B(B<T> &b) { cout << "In B copy ctor" << endl; }

    >
    > > B<T>& operator=(const B<T> &b) { cout << "In B assign." << endl;
    > > return *this; }

    >
    > > ~B(){ cout << "In B destructor" << endl; }

    >
    > > };

    >
    > > B<int> test()
    > > {
    > > B<int> returnVal;
    > > return returnVal;

    >
    > > }

    >
    > > int main()
    > > {
    > > B<int> b;
    > > b = test();

    >
    > The problem is that the compiler converts this to a copy-constructor
    > call like this 'B<int>(test())', however since your copy-constructor
    > takes a reference as a parameter this can not compile (since a
    > reference can not bind to the temporary returned by test()). To solve
    > this simply change the copy-constructor to 'B(const B<T> &b)'. In
    > general the parameters to copy-constructors should be const.
    >
    > --
    > Erik Wikström


    Thanks for the help and the explanation, that worked perfectly
     
    saxman, Jun 12, 2007
    #3
    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. Replies:
    4
    Views:
    486
    Brian MacBride
    Jul 4, 2003
  2. Replies:
    12
    Views:
    2,252
    Howard
    Jun 16, 2005
  3. Henrik Goldman
    Replies:
    2
    Views:
    451
    Andrey Tarasevich
    Dec 26, 2006
  4. Replies:
    8
    Views:
    453
    terminator
    Aug 29, 2007
  5. harry
    Replies:
    6
    Views:
    999
Loading...

Share This Page