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()
:
const
-qualified one that returns a reference to a const
vector (like the one shown above) 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.