Sinn von std::make_pair
-
CStoll schrieb:
Weil bei der Angabe von Template-Typen die Parameter nicht automatisch erkannt werden können. (make_pair() und ähnliche Funktionen wurden eingeführt, um genau diese Lücke zu schließen)
Warum kann es dann bei make_pair erkannt werden?
-
make_pair() ist eine Funktion - und für Funktionen gelten etwas andere Regeln als für Klassen (insbesondere kann der Compiler aus den Funktionsparametern (meist) die benötigten Typen herleiten).
-
Vielen Dank!
Klingt logisch ^^
-
CStoll schrieb:
make_pair() ist eine Funktion - und für Funktionen gelten etwas andere Regeln als für Klassen (insbesondere kann der Compiler aus den Funktionsparametern (meist) die benötigten Typen herleiten).
Naja, so ganz versteh ich es nicht. make_pair bekommt es ja hin, dass ein richtiges Objekt erzeugt wird. Wieso der Compiler jetzt die Typen bei Konstruktoren nicht herleiten kann, muss wohl in den Tiefen von C++ vergraben sein.
std::make_pair<int, int>(1,3); std::make_pair(1,3); std::pair<int, int> rr1(1,3); std::pair rr2(1,3); //Warum nicht, die Info ist doch genauso vorhanden wie beim zweiten make_pair?
-
@hmm: Du siehst das zu oberflächlich - bei Template-Klassen muß der exakte Typ angegeben werden, um eine Variable anlegen zu können (std::pair ist kein Typ, sondern eine Vorlage für viele mögliche Typen). Bei Template-Funktionen spart es Schreibarbeit, wenn man nicht immer die ellenlangen Typangaben angeben muß (und vermindert Redundanzen), aber bei Klassen war das nicht nötig.
(btw, irgendwo habe ich auch etwas von auto gelesen, um den richtigen Typ für eine Variable automatisch ermitteln zu lassen - afair eine Erweiterung für die nächste Standardversion)
-
CStoll schrieb:
... aber bei Klassen war das nicht nötig.
Soll heißen, es würde eigentlich gehen, aber keiner wollte es, also hat man es nicht gemacht?
-
Nein, bei Klassen mußt du sowieso die Parameter angeben, da kommst du nicht drum herum. Und für die wenigen Fälle, wo du ein anonymes Objekt anlegen willst, gibt es Pseudo-Konstruktoren wie make_pair().
-
Wie soll das auch bei Klassen gehen???

template<class T, class K> class Dummy { T t1; K k1; }; Dummy d; // öhm, und t1 und k1 sind vom Typ???Der Bezug zu den Typen IN der Klasse fehlt ja total. Ich muß irgendwie mitteilen, wie die Typen sind. Das kann der Compiler anhand der Informationen in Zeile 8 garnicht feststellen.
Bei einer Funktion, kann der Compiler das anhand der Parameter feststellen, weil ich die gezwungenermaßen übergeben muß. Das liegt irgendwie in der Natür der Sache.
template<class T, class K> void foo(T t1, K k1) { // mach irgendwas mit t1 und k1... } foo(123, 456); // sind Ints, und somit ist alles für den Compiler bekannt.in foo arbeite ich mit Daten die mir der User übergibt. Und daraus kann der Compiler den Typ feststellen.
-
Hi,
EDIT: Artchi war schneller, aber ein wenig mehr habe ich schon gesagt:
sagen wir einfach mal so: Bei Funktionsaufrufen hast Du implizit Typangaben (über die Parameter), die der Compiler verwenden kann -- bei Klassen nicht:
template <typename T> class myClass { T t; }; template <typename T> void f(T t); int main() { myClass a; // was soll der Compiler hier als T annehmen ? f(3); // Hier ist's klar: T => intDeswegen hat ein Compiler auch Probleme mit Funktionen, bei denen er das T nicht auflösen kann wie:
template <typename T> void f() { T t; };Aber ein wenig muss ich schon zustimmen: Man hätte den Compiler noch auf Sonderfälle testen lassen wie:
template <typename T> class myClass { T t; public: myClass(T); }; int main() { myClass a(3); // Hier könnte der Compiler annehmen, dass man ein myClass<int> haben möchte... aber das hätte wiederum andere häßliche Probleme erzeugt, wie
myClass a(3), b('x'), c(3.4); // haben alle unterschiedlichen Typ !Vermutlich sind die Komplikationen so einer Regelungen den Aufwand an Sonderregeln und Compilerbau (die ich mir immens vorstelle) nicht wert.
Gruß,
Simon2.
-
Vermutlich sind die Komplikationen so einer Regelungen den Aufwand an Sonderregeln und Compilerbau (die ich mir immens vorstelle) nicht wert.
Richtig! Wenn man die Postings des C++-Komitees verfolgt, wird man feststellen, das diese sehr gerne vieles "automatisieren" würden, aber die Komplexität für die Implementierung durch die Compiler-Hersteller das nicht gerechfertigt. Die würden auf die Barikaden gehen und dann können wir lange auf einen C++-konformen Compiler warten.

-
Simon2 schrieb:
Aber ein wenig muss ich schon zustimmen: Man hätte den Compiler noch auf Sonderfälle testen lassen wie:
template <typename T> class myClass { T t; public: myClass(T); }; int main() { myClass a(3); // Hier könnte der Compiler annehmen, dass man ein myClass<int> haben möchte... aber das hätte wiederum andere häßliche Probleme erzeugt, wie
myClass a(3), b('x'), c(3.4); // haben alle unterschiedlichen Typ !Vermutlich sind die Komplikationen so einer Regelungen den Aufwand an Sonderregeln und Compilerbau (die ich mir immens vorstelle) nicht wert.
genau das mein ich mit "es würde eigentlich gehen, aber keiner wollte es". Wobei "wollen" nicht ganz stimmt, sondern der Nutzen einfach nicht so groß wäre im Vergleich zum Aufwand. Man kann es ja jetzt fast genauso mit Funktionen lösen.
-
Artchi schrieb:
...die Komplexität für die Implementierung durch die Compiler-Hersteller das nicht gerechfertigt. Die würden auf die Barikaden gehen und dann können wir lange auf einen C++-konformen Compiler warten.

hmmmm schrieb:
...sondern der Nutzen einfach nicht so groß wäre im Vergleich zum Aufwand. Man kann es ja jetzt fast genauso mit Funktionen lösen.
Wobei es mir nicht nur (aber auch) um den Aufwand der Compilerhersteller ging, sondern auch um die "Komplexität im Regelwerk". Wenn man sich mal ansieht wie oft/regelmäßig hier das hier auftaucht:
myClass meinObjekt1("Simon2"), meinObjekt2(), meinObjekt2(7);... dann will ich nicht wissen, wie viele Fehler eine "implizite template-class-deduction" verursacht.
Gruß,
Simon2.