Hello I'm trying to transfer/move an element from one list (in the example foo) at (end()-1) to another list (in the example called bar) to position begin().
The only problem is that one of the lists is using an custom made allocator. Which probably results to the following error message:
../src/TestAllocator.cpp:120:28: error:
no matching function for call to
‘std::list<int>::splice ( std::_List_iterator<int>&,
std::list<int, CustomAllocator<int> >&,
std::_List_iterator<int>&)’
My Question here is:
Why is there an error message when splicing list elements from lists with different allocators?
And how can this be fixed?
#include <limits> // numeric_limits
#include <iostream>
#include <typeinfo> // typeid
// container
#include <vector>
#include <list>
#include <forward_list>
/// state stored as static member(s) of an auxiliary(=hilfs/zusatz) class
struct CustomAllocatorState {
static std::size_t m_totalMemAllocated;
};
std::size_t CustomAllocatorState::m_totalMemAllocated = 0;
/// @brief The @a custom allocator
/// @tparam T Type of allocated object
template<typename T>
class CustomAllocator {
public:
// type definitions
typedef std::size_t size_type; /** Quantities of elements */
typedef std::ptrdiff_t difference_type; /** Difference between two pointers */
typedef T* pointer; /** Pointer to element */
typedef const T* const_pointer; /** Pointer to constant element */
typedef T& reference; /** Reference to element */
typedef const T& const_reference; /** Reference to constant element */
typedef T value_type; /** Element type */
template<typename U>
struct rebind {
typedef CustomAllocator<U> other;
};
CustomAllocator() throw() {
std::cout << "construct " << typeid(T).name() << std::endl;
}
CustomAllocator(const CustomAllocator&) throw() {
std::cout << "copy construct " << typeid(T).name() << std::endl;
}
template<class U>
CustomAllocator() throw() {
}
~CustomAllocator() throw() {}
// allocate but don't initialize num elements of type T
pointer allocate(size_type num, const void* = 0) {
CustomAllocatorState::m_totalMemAllocated += num * sizeof(T);
// print message and allocate memory with global new
std::cout << "allocate " << num << " element(s)" << " of size "
<< sizeof(T) << std::endl;
pointer ret = (pointer) (::operator new(num * sizeof(T)));
std::cout << " allocated at: " << (void*) ret << std::endl;
return ret;
}
// deallocate storage p of deleted elements
void deallocate(pointer p, size_type num) {
CustomAllocatorState::m_totalMemAllocated -= num * sizeof(T);
// print message and deallocate memory with global delete
std::cout << "deallocate " << num << " element(s)" << " of size "
<< sizeof(T) << " at: " << (void*) p << std::endl;
::operator delete((void*) p);
}
// initialize elements of allocated storage p with value value
// no need to call rebind with this variadic template anymore in C++11
template<typename _U, typename ... _Args>
void construct(_U* p, _Args&&... args) {
::new ((void *) p) _U(std::forward<_Args>(args)...);
}
// destroy elements of initialized storage p
template<typename _U>
void destroy(_U* p) {
p->~_U();
}
// return address of values
pointer address (reference value) const {
return &value;
}
const_pointer address (const_reference value) const {
return &value;
}
// return maximum number of elements that can be allocated
size_type max_size () const throw() {
return std::numeric_limits<std::size_t>::max() / sizeof(T);
}
};
template<typename T, typename U>
inline bool operator==(const CustomAllocator<T>&, const CustomAllocator<U>&) {
return true;
}
template<typename T, typename U>
inline bool operator!=(const CustomAllocator<T>&, const CustomAllocator<U>&) {
return false;
}
int main() {
std::list<int, CustomAllocator<int>> foo;
std::list<int> bar; // aka std::list<int, std::allocator<int> > bar;
foo.push_back(23);
foo.push_back(12);
foo.push_back(8);
// transfer/move element in foo at end() to list bar at position begin()
auto pos = bar.begin();
auto other = foo;
auto it = --(foo.end());
bar.splice(pos, foo, it); // here the error: no matching function for call
std::cout << "---" << std::endl;
// debug output
std::cout << "Foo: ";
for (auto x : foo)
std::cout << x << " ";
std::cout << std::endl;
std::cout << "Bar: ";
for (auto x : bar)
std::cout << x << " ";
std::cout << std::endl;
std::cout << "alloc_count: " << CustomAllocatorState::m_totalMemAllocated << std::endl;
std::cout << "---" << std::endl;
std::cout << '\n';
return 0;
}