2016-05-04 22 views
2

Ich arbeite mit Standard-Container wie Vektor und Paar mit benutzerdefinierten Typen als Vorlage Argumente. Die meiste Zeit diese Template-Typen sind const qualifiziert, wie in:C++ - Konstante auf Template-Typ Parameter

std::vector<const std::pair<const customType, const double>> 

Hash() Operatoren und Vergleichsoperatoren == und < definiert wurden.

Problem tritt auf, wenn ich solche Werte zu Standard-Bibliotheksfunktionen wie partial_sort_copy, partial_sort und löschen übergebe. Aus irgendeinem Grund versuchen diese Funktionen schließlich, Zuweisungen zu den gegebenen Typen zu machen, was schließlich aufgrund der Überlastung bei der Kompilierung fehlschlägt.

Gibt es eine Möglichkeit, die Konflikte auf Schablonentypen für Vektor und Paar zu werfen? D. h., Gießen vector<const myType> bis vector<myType>.

Vielen Dank im Voraus.

EDIT: Jetzt mit widersprüchlichen minimalen Beispielcode!

// Non-working code: 
std::vector<const std::pair<const int, const double>> list{ { 3, 3. }, { 2, 2. }, { 1, 1. }, { 0, 0. } }; 
std::partial_sort(list.begin(), list.begin() + 2, list.end(), [](const std::pair<const int, const double>& x, const std::pair<const int, const double>& y){ return x.first < y.first; }); 

// This works, actually: 
std::vector<std::pair<int, double>> list{ { 3, 3. }, { 2, 2. }, { 1, 1. }, { 0, 0. } }; 
std::partial_sort(list.begin(), list.begin() + 2, list.end(), [](const std::pair<int, double>& x, const std::pair<int, double>& y){ return x.first < y.first; }); 

Was es über meinen Code ist, dass die Standardbibliothek nicht gefallen hat?

+1

Sie sollten wahrscheinlich nicht konstante Paare von const-Werten verwenden. Vielleicht würde es hilfreich sein, ein ADL-verfügbares 'swap' zu definieren, aber Sie müssen' std :: pair' ableiten, da es keine gute Idee ist, etwas in 'std' zu definieren. – bipll

+0

danke für deine antwort. Ich werde ADL nachschlagen. – jvier

+0

@bipll Es ist völlig erlaubt, Funktionsüberladung/Templates wie 'swap' und' hash' im std-Namespace zu definieren. – Johan

Antwort

3

Solche Container von Const-Typen sind undefiniertes Verhalten. A std::vector<const T> verwendet std::allocator<const T> als Zuweisungsart, und die Zuweisungsanforderungen geben an, dass der Werttyp ein nicht-konstanter Objekttyp sein muss.

ignorieren Auch das ...

Gibt es eine Möglichkeit, die consts heraus Vorlagentypen für Vektor- und Paar zu werfen? D. h., Gießen vector<const myType> bis vector<myType>.

Nr

Im Allgemeinen some_template<T> und some_template<const T> sind völlig unabhängig von Typen, so dass Sie nicht zwischen ihnen werfen kann. Im Gegensatz zu const some_template<T> und some_template<T> gibt es keine gültige Konvertierung zwischen ihnen.

Sie sollten also aufhören, Vektoren von const Objekten zu verwenden. Verwenden Sie stattdessen einen konstanten Vektor von nichtkonstanten Objekten.

+0

Hmmm. Das ist endlich etwas. Also, warum darf ich solche const-Constraints auf typlatierten Typen verwenden, wenn ihr Verhalten nicht definiert ist? Ich habe auch bemerkt, dass, während 'const myType const *' ein gültiger Typ ist, die Verwendung als Vektortyp als dupliziertes const-Qualifikationsmerkmal betrachtet wird.Ist das irgendwie mit meinem erklärten Problem verbunden? Vielen Dank! – jvier

+1

@jvier 'const T *' und 'T const *' sind die gleichen Typen. Du meintest wahrscheinlich "const T * const" (beachte das "const" nach dem Stern) stattdessen. – milleniumbug

+1

@jvier "undefined Verhalten" bedeutet, dass Sie es nicht tun dürfen, aber der Compiler darf keine Warnmeldung geben –