1

我找不到比直接粘贴在这里更简单的方法来解释我的问题(虽然是简化版本)。我有一个带有必要赋值运算符、默认构造函数和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]

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

4

3 回答 3

9

您的get()函数不是合格的,并且您正在通过复制构造函数中const的引用来调用它:const

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

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

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

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

如果你需要你的非const函数get(),因为你想允许客户端修改内部buffer(建议:考虑这是否真的是一个好主意),那么你将不得不提供两个重载get()

  • 一个const返回对const向量的引用的限定符(如上图所示)
  • const返回对可修改向量的引用的非限定向量(如原始向量get()
于 2013-06-07T09:18:29.723 回答
2

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

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

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

BufferContainer( const BufferContainer& other )

这意味着您只能constother.

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

于 2013-06-07T09:17:14.827 回答
1

other被作为const参考并且get是一个非常量方法。您不能从 const 引用调用非常量方法。

于 2013-06-07T09:18:26.840 回答