unique_ptr в std::set не может найти оператор‹, хотя он есть

Возможный дубликат:
Clang, std::shared_ptr и std::less/оператор‹

Так что да, в названии почти вся проблема. Как вы можете видеть из фрагмента ниже, я реализовал operator<, поэтому я понятия не имею, что происходит.

Вот код:

namespace {

struct Transition {
    string name;
    StatePtr toState;

    Transition(string s = string(), StatePtr state = nullptr)
      : name(move(s))
      , toState(move(state))
    {}

    friend bool operator==(Transition const& lhs, Transition const & rhs) {
      return lhs.name == rhs.name && lhs.toState == rhs.toState;
    }

    friend bool operator<(Transition const & lhs, Transition const & rhs);
  };

  struct State {
    string name;
    set<TransitionPtr> transitions;

    explicit State(string s = string())
      : name(move(s))
    {}

    void addTransition(string s, StatePtr sp = nullptr){
      TransitionPtr new_t = make_transition(s, sp);
      for(auto& t : transitions){
        if(t == new_t){
          return;
        }
      }

      transitions.insert(move(new_t)); // This is where the error happens.
    }

  };
}

bool operator<(StateMachine::Transition const & lhs, StateMachine::Transition const & rhs) {
 return lhs.toState.get() < rhs.toState.get();
}

и сообщение об ошибке:

В файле из ../llvm_opt_pass/cgd.cpp:3: В файле из /srv/scratch/sigubufo/clang/stable/3.1_src/llvm/include/llvm/Instructions.h:23: В файле из / srv/scratch/sigubufo/clang/stable/3.1_src/llvm/include/llvm/ADT/ArrayRef.h:13: В файле, включенном из /srv/scratch/sigubufo/clang/stable/3.1_src/llvm/include/llvm /ADT/SmallVector.h:24: В файле, включенном из /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/memory:85: /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/unique_ptr.h:486:14: ошибка: нет подходящей функции для вызова объекту типа 'std::less‹_CT>' return std::less‹_CT>()(__x.get(), __y.get()); ^~~~~~~~~~~~~~~~

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_function.h:237:20: примечание: при создании экземпляра шаблона функции специализация 'std::operator‹‹::StateMachine::Transition, std::default_delete‹::StateMachine::Transition>, ::StateMachine::Transition, std::default_delete‹::StateMachine::Transition> >' запрошена здесь { вернуть __x ‹ __y; } ^

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_tree.h:1285:13: примечание: при создании экземпляра функции-члена 'std::less::StateMachine::Transition, std::default_delete‹::StateMachine::Transition> > >::operator()' запрашивается здесь __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x )); ^

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_set.h:424:9: примечание: > в экземпляре функции специализация шаблона 'std::_Rb_tree::StateMachine::Transition, std::default_delete‹::StateMachine::Transition> >, std::unique_ptr‹::StateMachine::Transition, std::default_delete‹::StateMachine:: Transition> >, std::_Identity::StateMachine::Transition, std::default_delete‹::StateMachine::Transition> > >, std::less::StateMachine::Transition, std::default_delete‹::StateMachine: :Transition> > >, std::allocator::StateMachine::Transition, std::default_delete‹::StateMachine::Transition> > > ::_M_insert_unique::StateMachine::Transition, std::default_delete‹::StateMachine: :Transition> > >' запрошено здесь _M_t._M_insert_unique(std::move(__x)); ^

../llvm_opt_pass/cgd.cpp:72:17: примечание: при создании экземпляра функции-члена 'std::set::StateMachine::Transition, std::default_delete‹::StateMachine::Transition> >, std::less ::StateMachine::Transition, std::default_delete‹::StateMachine::Transition> > >, std::allocator::StateMachine::Transition, std::default_delete‹::StateMachine::Transition> > > >:: вставка запрошена здесь transitions.insert(move(new_t)); ^

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_function.h:236:7: примечание: функция-кандидат нежизнеспособна: неизвестное преобразование из "указателя" (он же "::StateMachine::Transition *") в "::StateMachine::Transition *&&&" > для 1-го аргумента; оператор()(const _Tp& __x, const _Tp& __y) const


person RedX    schedule 19.12.2012    source источник


Ответы (2)


Итак, решение такое же, как и для этого вопроса: Clang, std::shared_ptr и std::less/оператор‹ .

В основном это ошибка в type_traits из libstdc++.

person RedX    schedule 19.12.2012

Попробуйте предоставить собственный функтор в качестве альтернативы std::less.

struct cmp  {
    bool operator() ( const Transition& lhs, const Transition& rhs )  {
        return lhs.toState.get() < rhs.toState.get();
     }
 };

std::set< Transition, cmp > transitions;
person Marius Pirvu    schedule 19.12.2012
comment
Это не сработает, потому что RHS должен будет ссылаться на один и тот же объект, тем самым нарушая назначение unique_ptr. - person nacitar sevaht; 03.12.2013