Ich möchte eine sortierte Ansicht von std::vector<std::chrono::milliseconds>
, aber ich möchte nicht den ursprünglichen Container ändern. std::reference_wrapper
scheint perfekt dafür und es funktioniert gut für einen Vektor von ganzen Zahlen.Warum kann ich keinen Vektor von reference_wrapper <std :: chrono :: Millisekunden> sortieren?
Ich habe dieses kleine Beispiel erstellt:
#include <chrono>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
int main()
{
std::vector<int> numbers{1, 42, 3, 9, 5};
std::vector<std::reference_wrapper<int>> sorted_numbers(numbers.begin(), numbers.end());
std::sort(sorted_numbers.begin(), sorted_numbers.end());
std::cout << "Numbers: ";
for (const auto& n : numbers)
std::cout << n << ' ';
std::cout << '\n';
std::cout << "Sorted numbers: ";
for (const auto& n : sorted_numbers)
std::cout << n << ' ';
std::cout << '\n';
std::cout << "Numbers: ";
for (const auto& n : numbers)
std::cout << n << ' ';
std::cout << '\n';
std::vector<std::chrono::milliseconds> durations{std::chrono::milliseconds{1},
std::chrono::milliseconds{42},
std::chrono::milliseconds{3},
std::chrono::milliseconds{9},
std::chrono::milliseconds{5}};
std::vector<std::reference_wrapper<std::chrono::milliseconds>>
sorted_durations(durations.begin(), durations.end());
// std::sort(sorted_durations.begin(), sorted_durations.end());
std::cout << "Durations: ";
for (const auto& d : durations)
std::cout << d.count() << ' ';
std::cout << '\n';
std::cout << "Sorted durations: ";
for (const auto& d : sorted_durations)
std::cout << d.get().count() << ' ';
std::cout << '\n';
std::cout << "Durations: ";
for (const auto& d : durations)
std::cout << d.count() << ' ';
std::cout << '\n';
}
die die erwartete Ausgabe erzeugt (außer dass sorted_durations
ist natürlich nicht sortiert, da diese auf Kommentar wird):
Numbers: 1 42 3 9 5 Sorted numbers: 1 3 5 9 42 Numbers: 1 42 3 9 5 Durations: 1 42 3 9 5 Sorted durations: 1 42 3 9 5 Durations: 1 42 3 9 5
Wie Sie kann sehen, der ursprüngliche Vektor der Ganzzahlen numbers
ist unverändert durch die Sortieroperation auf sorted_numbers
getan - das ist genau das, was ich für die sorted_durations
Vektor auch will. Aber wenn ich diese Zeile auszeichne, wird mein Compiler sehr böse mit mir und ich muss zugeben, dass ich nicht herausfinden kann, was es mir zu sagen versucht. Mein Compiler Klirren ist ++ Version 3.8 und ich bauen das Beispielprogramm wie folgt:
clang++ -std=c++11 test.cc
Und hier ist die Fehlerausgabe erhalte ich:
In file included from test.cc:4:
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/algorithm:62:
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_algo.h:1935:11: error: invalid operands to binary expression
('std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >' and 'std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >')
if (*__i < *__first)
~~~~^~~~~~~~~
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_algo.h:5308:12: note: in instantiation of function template specialization
'std::__heap_select<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > *,
std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > > >
>' requested here
std::__heap_select(__first, __middle, __last);
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization
'std::partial_sort<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > *,
std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > > >
>' requested here
_GLIBCXX_STD_A::partial_sort(__first, __last, __last);
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_algo.h:5460:9: note: in instantiation of function template specialization
'std::__introsort_loop<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > *,
std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > > >,
long>' requested here
std::__introsort_loop(__first, __last,
^
test.cc:35:10: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >
*, std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > >
> >' requested here
std::sort(sorted_durations.begin(), sorted_durations.end());
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/chrono:488:7: note: candidate template ignored: could not match 'duration' against 'reference_wrapper'
operator<(const duration<_Rep1, _Period1>& __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/chrono:667:7: note: candidate template ignored: could not match 'time_point' against 'reference_wrapper'
operator<(const time_point<_Clock, _Dur1>& __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair' against 'reference_wrapper'
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator' against
'reference_wrapper'
operator<(const reverse_iterator<_Iterator>& __x,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator' against
'reference_wrapper'
operator<(const reverse_iterator<_IteratorL>& __x,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h:1055:5: note: candidate template ignored: could not match 'move_iterator' against 'reference_wrapper'
operator<(const move_iterator<_IteratorL>& __x,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h:1061:5: note: candidate template ignored: could not match 'move_iterator' against 'reference_wrapper'
operator<(const move_iterator<_Iterator>& __x,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector' against 'reference_wrapper'
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:2569:5: note: candidate template ignored: could not match 'basic_string' against 'reference_wrapper'
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:2581:5: note: candidate template ignored: could not match 'basic_string' against 'reference_wrapper'
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:2593:5: note: candidate template ignored: could not match 'const _CharT *' against
'std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >'
operator<(const _CharT* __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/array:238:5: note: candidate template ignored: could not match 'array' against 'reference_wrapper'
operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/tuple:824:5: note: candidate template ignored: could not match 'tuple' against 'reference_wrapper'
operator<(const tuple<_TElements...>& __t,
^
In file included from test.cc:4:
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/algorithm:62:
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_algo.h:61:
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_heap.h:235:35: error: invalid operands to binary expression ('std::reference_wrapper<std::chrono::duration<long,
std::ratio<1, 1000> > >' and 'std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >')
if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_heap.h:407:9: note: in instantiation of function template specialization
'std::__adjust_heap<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > *,
std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > > >,
long, std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > >' requested here
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value));
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_algo.h:1933:12: note: in instantiation of function template specialization
'std::make_heap<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > *,
std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > > >
>' requested here
std::make_heap(__first, __middle);
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_algo.h:5308:12: note: in instantiation of function template specialization
'std::__heap_select<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > *,
std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > > >
>' requested here
std::__heap_select(__first, __middle, __last);
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_algo.h:2310:24: note: in instantiation of function template specialization
'std::partial_sort<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > *,
std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > > >
>' requested here
_GLIBCXX_STD_A::partial_sort(__first, __last, __last);
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_algo.h:5460:9: note: in instantiation of function template specialization
'std::__introsort_loop<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > *,
std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > > >,
long>' requested here
std::__introsort_loop(__first, __last,
^
test.cc:35:10: note: in instantiation of function template specialization 'std::sort<__gnu_cxx::__normal_iterator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >
*, std::vector<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >, std::allocator<std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > > > >
> >' requested here
std::sort(sorted_durations.begin(), sorted_durations.end());
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/chrono:488:7: note: candidate template ignored: could not match 'duration' against 'reference_wrapper'
operator<(const duration<_Rep1, _Period1>& __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/chrono:667:7: note: candidate template ignored: could not match 'time_point' against 'reference_wrapper'
operator<(const time_point<_Clock, _Dur1>& __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_pair.h:220:5: note: candidate template ignored: could not match 'pair' against 'reference_wrapper'
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h:297:5: note: candidate template ignored: could not match 'reverse_iterator' against
'reference_wrapper'
operator<(const reverse_iterator<_Iterator>& __x,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h:347:5: note: candidate template ignored: could not match 'reverse_iterator' against
'reference_wrapper'
operator<(const reverse_iterator<_IteratorL>& __x,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h:1055:5: note: candidate template ignored: could not match 'move_iterator' against 'reference_wrapper'
operator<(const move_iterator<_IteratorL>& __x,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h:1061:5: note: candidate template ignored: could not match 'move_iterator' against 'reference_wrapper'
operator<(const move_iterator<_Iterator>& __x,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_vector.h:1421:5: note: candidate template ignored: could not match 'vector' against 'reference_wrapper'
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:2569:5: note: candidate template ignored: could not match 'basic_string' against 'reference_wrapper'
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:2581:5: note: candidate template ignored: could not match 'basic_string' against 'reference_wrapper'
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:2593:5: note: candidate template ignored: could not match 'const _CharT *' against
'std::reference_wrapper<std::chrono::duration<long, std::ratio<1, 1000> > >'
operator<(const _CharT* __lhs,
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/array:238:5: note: candidate template ignored: could not match 'array' against 'reference_wrapper'
operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
^
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/tuple:824:5: note: candidate template ignored: could not match 'tuple' against 'reference_wrapper'
operator<(const tuple<_TElements...>& __t,
^
Es geht tatsächlich für ein bisschen länger, aber Stackoverflow wird nicht Lassen Sie mich alle 55000 Zeichen des Fehlers posten.
Kann mir bitte jemand erklären, was ich falsch mache oder warum das einfach nicht möglich ist (wenn das der Fall ist)?
Es scheint, wie std :: reference_wrapper nicht Binäroperators bereitstellt < – Incomputable
auf [Bezugsseite] (http://de.cppreference.com/w/cpp/utility/functional/reference_wrapper) es gibt keine Operatoren zum Vergleich, also denke ich, dass Sie Ihre eigenen schreiben müssen. – Incomputable
Wie viele Elemente enthält der Vektor? Kannst du es nicht einfach kopieren? Das macht man jetzt sowieso mit dem 'reference_wrapper'-Vektor. –