当类用作映射值时,复制构造函数不起作用

时间:2013-06-07 09:14:37

标签: c++

我找不到一种更简单的方法来解释我的问题,而不是直接粘贴它(虽然简化版本)。 我有一个带有必要赋值运算符,默认构造函数和common复制构造函数的模板类。当我尝试在我的代码中使用此类时,我得到如下错误:

#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;
}

,错误是:

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]

如果您帮助我解决此问题的方法,我将不胜感激,更重要的是,告诉我为什么会出现此错误。 感谢

3 个答案:

答案 0 :(得分:9)

您的get()函数不是const - 符合条件,您通过复制构造函数中对const的引用来调用它:

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

这就是编译器抱怨的原因。您无法通过对const的引用来调用非const函数。引用const意味着您不会修改引用对象的状态,因此您只能调用承诺不修改对象状态的函数。这就是成员函数的const限定符所用的 - 来做出这个承诺。

因此,您的成员函数get()应该被限定为const,并返回对const向量的引用:

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

如果您需要非const函数get(),因为您希望允许客户修改内部buffer(建议:考虑这是否真的是个好主意),那么您必须提供两个重载get()

  • 一个const - 合格的一个返回对const向量的引用(如上所示)
  • const合格的,返回对可修改向量的引用(如原始get()

答案 1 :(得分:2)

这意味着您应该提供const方法的get()版本:

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

因为复制构造函数正确地使用const引用:

BufferContainer( const BufferContainer& other )

这意味着您只能在const上调用other方法。

请注意,const get()版本的返回类型是const引用。这是const正确性所必需的。

答案 2 :(得分:1)

other被视为const引用,get是非const方法。你不能从const引用中调用非const方法。