Mam std::vector<std::pair<int,std::pair<Bone,std::string> > >

Próbuję go posortować za pomocą standardowego sortowania, oczekując, że jest posortowany według int, ale zamiast tego otrzymuję 21 błędów związanych z wywołaniem sortowania.

Co może być nie tak?

Kod:

std::vector<std::pair<int,std::pair<Bone,std::string> > > tempBones;
std::sort(tempBones.begin(),tempBones.end());

Błędy:

Błąd 1 błąd C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)': nie można wydedukować argumentu szablonu dla 'const std::basic_string<_Elem,_Traits,_Alloc> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 102

Błąd 2 błąd C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)': nie można wydedukować argumentu szablonu dla 'const _Elem *' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 102

Błąd 3 błąd C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)': nie można wydedukować argumentu szablonu dla 'const std::basic_string<_Elem,_Traits,_Alloc> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 102

Błąd 4 błąd C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)': nie można wydedukować argumentu szablonu dla 'const std::_Tree<_Traits> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 102

Błąd 5 błąd C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)': nie można wydedukować argumentu szablonu dla 'const std::vector<_Ty,_Alloc> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 102

Błąd 6 błąd C2784: 'bool std::operator <(const std::list<_Ty,_Ax> &,const std::list<_Ty,_Ax> &)': nie można wydedukować argumentu szablonu dla 'const std::list<_Ty,_Ax> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 102

Błąd 7 błąd C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)': nie można wydedukować argumentu szablonu dla 'const std::reverse_iterator<_RanIt> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 102

Błąd 8 błąd C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)': nie można wydedukować argumentu szablonu dla 'const std::_Revranit<_RanIt,_Base> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 102

Błąd 9 błąd C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)': nie można wydedukować argumentu szablonu dla 'const std::pair<_Ty1,_Ty2> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 102

Błąd 10 błąd C2676: binarny '<': 'const skl::Bone' nie definiuje tego operatora ani konwersji na typ akceptowalny przez wstępnie zdefiniowany operator c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 10

Błąd 11 błąd C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)': nie można wydedukować argumentu szablonu dla 'const std::basic_string<_Elem,_Traits,_Alloc> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

Błąd 12 błąd C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)': nie można wydedukować argumentu szablonu dla 'const _Elem *' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

Błąd 13 błąd C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)': nie można wydedukować argumentu szablonu dla 'const std::basic_string<_Elem,_Traits,_Alloc> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

Błąd 14 błąd C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)': nie można wydedukować argumentu szablonu dla 'const std::_Tree<_Traits> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

Błąd 15 błąd C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)': nie można wydedukować argumentu szablonu dla 'const std::vector<_Ty,_Alloc> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

Błąd 16 błąd C2784: 'bool std::operator <(const std::list<_Ty,_Ax> &,const std::list<_Ty,_Ax> &)': nie można wydedukować argumentu szablonu dla 'const std::list<_Ty,_Ax> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

Błąd 17 błąd C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)': nie można wydedukować argumentu szablonu dla 'const std::reverse_iterator<_RanIt> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

Błąd 18 błąd C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)': nie można wydedukować argumentu szablonu dla 'const std::_Revranit<_RanIt,_Base> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

Błąd 19 błąd C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)': nie można wydedukować argumentu szablonu dla 'const std::pair<_Ty1,_Ty2> &' z 'const skl::Bone' c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

Błąd 20 błąd C2676: binarny '<': 'const skl::Bone' nie definiuje tego operatora ani konwersji na typ akceptowalny przez wstępnie zdefiniowany operator c:\Program Files\Microsoft Visual Studio 9.0\VC\include\utility 103

2
jmasterx 18 sierpień 2011, 04:38

2 odpowiedzi

Najlepsza odpowiedź

Dlaczego spodziewasz się, że zostanie posortowany według int? Każdy container<T> jest sortowany według T, a sortowanie wymaga, aby było mniej niż porównanie dla T. Teraz dla pair<S,T> istnieje operator<, zdefiniowany jako uporządkowanie leksykograficzne, ale wymaga to porównywalności zarówno S, jak i T:

// lexicographic compare:
bool operator<(pair<S,T> a, pair<S,T> b)
{
  return a.first < b. first || (!(b.first < a.first) && (a.second < b.second));
  //                                                    ^^^^^^^^^^^^^^^^^^^^^^^
} //                                                     compare second type!

Przesuwając się w dół rekurencyjnie, potrzebujesz Bone, aby być mniej niż porównywalne. Sprawdź każdy zakład, że nie zaimplementowałeś operatora porównania dla tego typu!

Edytuj: Zgodnie z Twoją aktualizacją to właśnie jest Twój problem.

Uwaga: Możesz się zastanawiać, dlaczego porównanie leksykograficzne jest ustawieniem domyślnym: jest to jedyne sensowne porównanie, dla którego !(x < y) && !(y < x) jest identyczne z x == y, pod warunkiem, że to samo obowiązuje dla obu podtypów osobno .

Aktualizacja: jeśli chcesz zamawiać tylko od pierwszego członka, powinieneś napisać niestandardowy predykat porównawczy lub zamiast tego użyć wielu map.

Komparator niestandardowy:

template <typename S, typename T>
bool PairCompareOnlyFirst(const std::pair<S,T> & a, const std::pair<S,T> & b)
{
  return a.first < b.first;
}

std::sort(v.begin(), v.end(), PairCompareOnlyFirst);

Zauważ, że sort może zmienić kolejność elementów z tym samym kluczem. Jeśli chcesz, aby zachowały swoją względną kolejność, użyj zamiast tego stable_sort.

Multimapa:

typedef std::multimap<int, std::pair<Bone,std::string> > myMapType;

Multimapa jest bardziej skomplikowaną strukturą niż wektor, a jej elementy są zawsze uporządkowane według wartości klucza, tj. Twojego int. Który z nich jest lepszy, zależy od tego, co robisz.

11
Kerrek SB 18 sierpień 2011, 05:13
Chcę tylko posortować według pierwszego, który jest int
 – 
jmasterx
18 sierpień 2011, 04:47
@Milo: Zaktualizowano, aby odpowiedzieć na to pytanie.
 – 
Kerrek SB
18 sierpień 2011, 04:50

Bez zobaczenia błędu nie mogę być tego pewien, ale należy zauważyć, że std::pair nie sortuje tylko według pierwszej wartości; używa również drugiej wartości, jeśli jest to konieczne do zerwania remisów. W kontekście std::map nie stanowi to problemu, ponieważ wewnętrznie mapa używa niestandardowego komparatora zamiast domyślnego operatora<, ale jeśli sortujesz pary naturalnie, kolejność może uwzględniać drugi element.

Z tego powodu, jeśli nie zdefiniowałeś operatora< dla Bone, otrzymasz błąd kompilatora, ponieważ kod szablonu dla operatora< pary będzie próbował go użyć. Co więcej, otrzymasz kilka poważnych błędów kompilatora, ponieważ kompilator zgłosi błąd dopiero po utworzeniu instancji szablonów sortowania i parowania.

Mam nadzieję że to pomoże!

1
templatetypedef 18 sierpień 2011, 04:50