webentwicklung-frage-antwort-db.com.de

Warum brachte der C++ 17-Standard keine partiellen Argumentabzüge für Klassenvorlagen?

Einer der Orte, an denen ich hoffte, den neuen Vorlagenargumentabzug nutzen zu können, war die Konstruktion von std::sets/std::maps/anderen Containern mit benutzerdefinierten Komparatoren. Mein Ziel ist es, eine einzeilige Anweisung zu erstellen, mit der eine effiziente Menge erstellt wird mit einem Lambda-Komparator. Was ich seit C++ 11 tun kann, ist:

std::set<int, std::function<bool(int, int)>> s([](int a, int b) {return a > b;});

Da es jedoch std::function verwendet, ist es merklich langsamer.

Eine andere Option ist:

auto mycomp = [](int a, int b) {return a > b; };
std::set<int, decltype(mycomp)> s(mycomp);

Es erledigt die Arbeit, aber 1) Es erfordert 2 Zeilen und die Erstellung der Variable mycomp 2) Ich muss den Typ von mycomp explizit übergeben.

Wie ich auf den Referenzseiten gelesen habe, enthält keiner der Standardbehälter einen Abzugshilfen für diese Art von Situation. Leider kann das mit dem aktuellen Sprachstandard (C++ 17) nicht einmal gemacht werden, wie man findet:

Die Ableitung von Klassenvorlagenargumenten wird nur durchgeführt, wenn keine Vorlagenargumentliste vorhanden ist. Wenn eine Vorlagenargumentliste angegeben ist, findet keine Ableitung statt.

Was ist die Begründung dafür? Warum erlaubten sie keinen partiellen Argumentabzug? Ich denke, es gibt einige Probleme, die ich übersehen habe, aber meiner Meinung nach wäre es mehr als hilfreich.

13
Kaznov

In einer Zeile (C++ 17)

std::set s(std::initializer_list<int>{}, [](int a, int b) {return a > b; });
11
max66

Alternativ können Sie noch den alten make_xxx erstellen.

template <typename T, typename COMP>
std::set<T, COMP> make_set(COMP comp)
{
    return std::set<T, COMP>{comp};
}


auto s = make_set<int>([](int a, int b) {return a > b; });
10
Jarod42

Was Sie tun sollten, ist das Schreiben eines Komparator-Funktortyps, so dass Sie bei der Verwendung Ihres Sets nicht darauf zugreifen müssen. Es wird viel mehr Codezeilen geben (die Grausamkeit!), Ist aber in praktisch jeder Hinsicht besser:

struct MyComparator
{
    bool operator()(int a, int b) const { ...; }
};
using MySet = std::set<int, MyComparator>;

Und von da an erstellen Sie einfach Ihr individuell sortiertes Set dort, wo Sie es benötigen.

5
rubenvb

Aufgrund der Mehrdeutigkeit wird es angezeigt, wenn Vorlagenparameter mit Standardwert vorhanden sind. Auch bei variadischen Vorlagen.

0
code707