2016-04-17 2 views
1

Здесь я определил свой собственный дебит, но не уверен, почему он не работает. Во-вторых, существует ли какой-либо способ не использовать цикл for_each и просто определять, используя его в момент объявления set, все объекты автоматически удаляются, когда заданный объект выходит из области видимости.std :: set deleter в C++ не работает

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

Ошибка компилятора:

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)' 
+1

Определение "не работает." Полностью объясните, что вы ожидаете, и что на самом деле происходит. – Cornstalks

ответ

2

код, предоставленный оленья кожа компиляции по нескольким причинам:

  1. пропавшим без вести аргумент шаблона в Deleter
  2. Ваше устройство сравнения сравнивает, когда необходимо сравнить A *

Если вы не используете указатели, тогда ваши объекты будут удалены, когда набор выходит за рамки.

Alternativly вы можете использовать зЬй: unique_ptr, код ammended ниже:

#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 std::unique_ptr<A>& lhs, const std::unique_ptr<A>& rhs) const 
    { 
       return lhs->intake() < rhs->intake(); 
    } 
}; 
int main() 
{ 
    set <std::unique_ptr<A> ,A_comp> s; 
    s.emplace(std::unique_ptr<A>(new A(40))); 
    s.emplace(std::unique_ptr<A>(new A(10))); 
    s.emplace(std::unique_ptr<A>(new A(30))); 
    s.emplace(std::unique_ptr<A>(new A(20))); 
    for(auto it = s.begin(); it != s.end() ; it++) 
     (*it)->show(); 
    return 0; 
}