Here I have defined my own deleter , but not sure why isn't working . Second is there any way of not using for_each loop and just defining deleter using it at the time of set declaration makes all objects get deleted automatically when the set object goes out of scope .
#include <iostream>
#include <memory>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
class A
{
int i;
public:
A(int pi):i(pi) {}
int intake() const { return i; }
void show() { cout<<i<<endl; }
~A() { cout<<"Destructor : "<<i<<endl; }
};
template <typename T>
struct Deleter
{
void operator () (T *ptr)
{
delete ptr;
}
};
struct A_comp
{
bool operator() (const A & lhs, const A & rhs) const
{
return lhs.intake() < rhs.intake();
}
};
int main()
{
set <A *,A_comp> s;
s.emplace(new A(40));
s.emplace(new A(10));
s.emplace(new A(30));
s.emplace(new A(20));
set <A *,A_comp>::iterator it;
for(it = s.begin(); it != s.end() ; it++)
(*it)->show();
for_each (s.begin (), s.end (), Deleter()); // Line 41
return 0;
}
Compiler Error :
In function 'int main()': 41:43: error: missing template arguments before '(' token In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h: In instantiation of 'std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = A*; _Val = A*; _KeyOfValue = std::_Identity<A*>; _Compare = A_comp; _Alloc = std::allocator<A*>; std::_Rb_tree<_Key, _Val,
_KeyOfValue, _Compare, _Alloc>::key_type = A*]': /usr/include/c++/4.9/bits/stl_tree.h:1748:55: required from 'std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key,
_Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_unique(_Args&& ...) [with _Args = {A*}; _Key = A*; _Val = A*; _KeyOfValue = std::_Identity<A*>; _Compare = A_comp; _Alloc = std::allocator<A*>]' /usr/include/c++/4.9/bits/stl_set.h:453:64: required from 'std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>,
_Compare, typename __gnu_cxx::__alloc_traits<_Allocator>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::emplace(_Args&& ...) [with
_Args = {A*}; _Key = A*; _Compare = A_comp; _Alloc = std::allocator<A*>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename
__gnu_cxx::__alloc_traits<_Allocator>::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<A*>]' 34:23: required from here /usr/include/c++/4.9/bits/stl_tree.h:1445:11: error: invalid user-defined conversion from 'const key_type {aka A* const}' to 'const A&' [-fpermissive]
__comp = _M_impl._M_key_compare(__k, _S_key(__x));
^ 11:5: note: candidate is: A::A(int) <near match> 11:5: note: no known conversion for argument 1 from 'const key_type {aka A* const}' to 'int' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1445:11: error: invalid conversion from 'std::_Rb_tree<A*, A*, std::_Identity<A*>, A_comp, std::allocator<A*> >::key_type {aka A*}' to 'int' [-fpermissive]
__comp = _M_impl._M_key_compare(__k, _S_key(__x));
^ 11:5: note: initializing argument 1 of 'A::A(int)' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1445:11: error: invalid user-defined conversion from 'A* const' to 'const A&' [-fpermissive]
__comp = _M_impl._M_key_compare(__k, _S_key(__x));
^ 11:5: note: candidate is: A::A(int) <near match> 11:5: note: no known conversion for argument 1 from 'A* const' to 'int' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1445:11: error: invalid conversion from 'A*' to 'int' [-fpermissive]
__comp = _M_impl._M_key_compare(__k, _S_key(__x));
^ 11:5: note: initializing argument 1 of 'A::A(int)' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1456:7: error: invalid user-defined conversion from 'A* const' to 'const A&' [-fpermissive]
if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
^ 11:5: note: candidate is: A::A(int) <near match> 11:5: note: no known conversion for argument 1 from 'A* const' to 'int' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1456:7: error: invalid conversion from 'A*' to 'int' [-fpermissive]
if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
^ 11:5: note: initializing argument 1 of 'A::A(int)' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1456:7: error: invalid user-defined conversion from 'const key_type {aka A* const}' to 'const A&' [-fpermissive]
if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
^ 11:5: note: candidate is: A::A(int) <near match> 11:5: note: no known conversion for argument 1 from 'const key_type {aka A* const}' to 'int' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1456:7: error: invalid conversion from 'std::_Rb_tree<A*, A*, std::_Identity<A*>, A_comp, std::allocator<A*> >::key_type {aka A*}' to 'int' [-fpermissive]
if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
^ 11:5: note: initializing argument 1 of 'A::A(int)' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h: In instantiation of 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type) [with _Key = A*; _Val = A*; _KeyOfValue = std::_Identity<A*>; _Compare = A_comp; _Alloc = std::allocator<A*>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<A*>; std::_Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_Base_ptr = std::_Rb_tree_node_base*; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<A*>*]': /usr/include/c++/4.9/bits/stl_tree.h:1750:65: required from 'std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key,
_Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_unique(_Args&& ...) [with _Args = {A*}; _Key = A*; _Val = A*; _KeyOfValue = std::_Identity<A*>; _Compare = A_comp; _Alloc = std::allocator<A*>]' /usr/include/c++/4.9/bits/stl_set.h:453:64: required from 'std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>,
_Compare, typename __gnu_cxx::__alloc_traits<_Allocator>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::emplace(_Args&& ...) [with
_Args = {A*}; _Key = A*; _Compare = A_comp; _Alloc = std::allocator<A*>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename
__gnu_cxx::__alloc_traits<_Allocator>::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<A*>]' 34:23: required from here /usr/include/c++/4.9/bits/stl_tree.h:1693:8: error: invalid user-defined conversion from 'A* const' to 'const A&' [-fpermissive]
|| _M_impl._M_key_compare(_S_key(__z),
^ 11:5: note: candidate is: A::A(int) <near match> 11:5: note: no known conversion for argument 1 from 'A* const' to 'int' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1693:8: error: invalid conversion from 'A*' to 'int' [-fpermissive]
|| _M_impl._M_key_compare(_S_key(__z),
^ 11:5: note: initializing argument 1 of 'A::A(int)' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1693:8: error: invalid user-defined conversion from 'A* const' to 'const A&' [-fpermissive]
|| _M_impl._M_key_compare(_S_key(__z),
^ 11:5: note: candidate is: A::A(int) <near match> 11:5: note: no known conversion for argument 1 from 'A* const' to 'int' In file included from /usr/include/c++/4.9/set:60:0,
from 4: /usr/include/c++/4.9/bits/stl_tree.h:1693:8: error: invalid conversion from 'A*' to 'int' [-fpermissive]
|| _M_impl._M_key_compare(_S_key(__z),
^ 11:5: note: initializing argument 1 of 'A::A(int)'
The code provided doesnt compile for a few reasons :
If you dont use pointers then your objects will be deleted when the set goes out of scope.
Alternativly you can use std:unique_ptr, code ammended below :