GCC-Fehlermeldung "default argument for parameter of type ... has type ..." beheben
Problem:
Du triffst auf eine GCC-Fehlermeldung der Form
error: default argument for parameter of type <some type> has type <some other type>Fehlerquelle:
Irgendwo in deinem Code hast du eine Funktion mit einem Standardargument wie diesem:
void doSomething(int arg1, std::set<std::string> arg2 = 15) {/*...*/}Mindestens eines der Argumente dieser Funktion hat Standardargumente (im obigen Beispiel nur arg2), die nicht zu ihrem Typ passen (mit anderen Worten, der Argumenttyp kann nicht mit dem angegebenen Standardwert initialisiert werden).
Im obigen Beispiel würde arg2, der den Typ std::set<std::string> hat, mit der Zahl 15 initialisiert werden, wenn doSomething() mit nur einem Argument aufgerufen wird.
Natürlich macht es keinen Sinn, ein std::set<std::string> mit einer Zahl zu initialisieren.
Hinweis: Die meisten STL-Container haben einen Konstruktor, der mit einem einzelnen integer-ähnlichen Argument aufgerufen werden kann (der sie mit einer bestimmten Größe oder Kapazität initialisiert), aber std::set nicht!
Ursache identifizieren
Normalerweise geben die Datei und die Zeilennummer in der Fehlermeldung die Position der Funktion an, die den Fehler verursacht. Wenn die Funktion, die den Fehler verursacht, jedoch eine Template-Funktion ist, wird normalerweise die Zeile des Funktionsaufrufs (und die entsprechende Datei) in der Fehlermeldung aufgeführt. Die Datei und die Zeile, in der die Template-Funktion deklariert ist, ist normalerweise im Fehlerprotokoll nicht sichtbar, also lass dich davon nicht verwirren.
Dieser Fehler wird immer durch eine fehlerhafte Funktionsdeklaration verursacht und nicht durch den Code innerhalb der Klammern der Funktion (C++11-Lambda-Funktionen können diesen Fehler ebenfalls verursachen).
Fehler beheben
Überprüfe alle Standardargumente in deiner Funktionsdeklaration. Vielleicht sieht eines verdächtig aus – wenn nicht, führe Folgendes für jedes Standardargument aus:
Prüfe, ob der Typ der Funktion einen Konstruktor hat, der mit den angegebenen Typen aufgerufen werden kann. Wenn er keinen solchen Konstruktor hat, ersetze ihn durch ein gültiges Standardargument.
Wenn das nicht funktioniert, ersetze die Standardargumente nacheinander durch Alternativen.
Mögliche Falle: Konstruktoren, die mit dem Schlüsselwort explicit deklariert wurden, müssen explizit im Standardargument aufgerufen werden (siehe auch den Sonderfall unten).
In einigen Fällen kann dieser Fehler auch dadurch verursacht werden, dass eine Referenz wie ein Wert initialisiert wird. Wenn die obigen Lösungen das Problem nicht lösen, versuche, das & vom Argumenttyp zu entfernen!
Sonderfall
Ich bin einmal auf diese seltsame Fehlermeldung gestoßen:
error: default argument for parameter of type `std::string& {aka std::basic_string<char>&}' has type `const char [1]'Sie wurde durch eine Template-Funktion wie diese verursacht:
template<typename T> void doSomething(std::string arg = "") {/*...*/}Es stellt sich heraus, dass GCC das nicht korrekt interpretieren kann ("" sollte einen leeren String initialisieren – anscheinend funktioniert es, wenn es keine Template-Funktion ist).
Die Deklaration durch
template<typename T> void doSomething(std::string arg = std::string()) {/*...*/}hat funktioniert. Wenn du keinen leeren String als Standardwert möchtest, könntest du eine Deklaration wie diese verwenden (mit expliziten Konstruktoraufrufen):
template<typename T> void doSomething(std::string arg = std::string("abc")) {/*...*/}Du musst auch ein solches Konstrukt verwenden, wenn du einen expliziten Konstruktor verwenden möchtest (= Konstruktor, der mit dem Schlüsselwort explicit deklariert wurde).