简体   繁体   中英

copy constructor doesn't work when the class is used as a map value

I can't find a simpler way to explain my problem than straight pasting it here(a simplified version though). I have a templated class with necessary assignment operator, default constructor and a common copy constructor. when I try to use this class in my code I get an error as follows:

#include<map>
#include<vector>

template<class T>
class BufferContainer
{
public:

    BufferContainer& operator=(BufferContainer& other)
    {
        buffer = other.get();
        return *this;
    }

    BufferContainer( const BufferContainer& other ) :
        buffer( other.get() )
     {
     }

    BufferContainer(){
    }

    std::vector<T>& get() {
            return buffer;
    }

    void add(T value) {

        buffer.push_back(value);
    }

    std::vector<T> buffer;
};

int main()
{
    std::map<int, BufferContainer<int> > myMap;
    myMap[1].add(1);
    return 1;
}

and the error is:

Practice $ g++ template.cpp 
template.cpp: In instantiation of ‘BufferContainer<T>::BufferContainer(const BufferContainer<T>&) [with T = int; BufferContainer<T> = BufferContainer<int>]’:
/usr/include/c++/4.7/bits/stl_pair.h:105:31:   required from ‘std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = const int; _T2 = BufferContainer<int>]’
/usr/include/c++/4.7/bits/stl_map.h:458:11:   required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = BufferContainer<int>; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, BufferContainer<int> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = BufferContainer<int>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]’
template.cpp:38:9:   required from here
template.cpp:16:26: error: passing ‘const BufferContainer<int>’ as ‘this’ argument of ‘std::vector<T>& BufferContainer<T>::get() [with T = int]’ discards qualifiers [-fpermissive]

I will appreciate if you help me with the methods to solve this issue and, more importantly, tell me why i got this error. thanks

Your get() function is not const -qualified, and you are invoking it through a reference to const in your copy-constructor:

BufferContainer( const BufferContainer& other ) :
//               ^^^^^
    buffer( other.get() )
//          ^^^^^^^^^^^
{
}

This is why the compiler is complaining. You cannot call a non- const function through a reference to const . Having a reference to const means you're not going to modify the state of the referenced object, so you can only invoke functions that promise not to modify the object's state. That's what the const qualifier on member functions is for - to make that promise.

Therefore, your member function get() should be qualified as const , and return a reference to a const vector:

std::vector<T> const& get() const 
//             ^^^^^        ^^^^^
{
    return buffer;
}

If you need your non- const function get() because you want to allow clients to modify the internal buffer (advice: consider whether this is really a good idea), then you will have to provide two overloads of get() :

  • A const -qualified one that returns a reference to a const vector (like the one shown above)
  • A non- const -qualified one that returns a reference to a modifiable vector (like the original get() )

What it means is that you should provide a const version of your get() method:

const std::vector<T>& get() const 
{
    return buffer;
}

since the copy constructor rightly takes a const reference:

BufferContainer( const BufferContainer& other )

This means you can only call const methods on other .

Note that the return type is of the const version of get() is a const reference. This is required for const correctness.

other is taken as const reference and get is a non-const method. You can't call a non-const method from a const reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM