Wie benutze ich generische Funktion in C ++?

8

Ich habe diesen Code geschrieben, in dem, wenn ich die vorletzte Zeile auskommentiere, bekomme ich Fehler - "Vorlage Argument Abzug / Ersatz fehlgeschlagen:". Liegt es an einer Beschränkung auf generische Funktionen in C ++? Auch mein Programm druckt keine Floating-Antwort für das Array b . Kann ich dafür etwas tun? (Entschuldigung für das Stellen von 2 Fragen im einzelnen Beitrag.)
P.S: Ich habe gerade angefangen, C ++ zu lernen.

%Vor%


EDIT 1: Nach dem Ändern von 40 auf 40.0 funktioniert der Code. Hier ist der Output, den ich bekomme:
6
6
16
46
Ich bekomme immer noch nicht die schwebende Antwort im 2. Fall. Irgendein Vorschlag ?

    
shane 27.08.2015, 14:15
quelle

7 Antworten

19

Der Grund ist, dass der Compiler den Typ für T nicht ableiten kann.

Wie sollte es verstehen, was T für Ihr letztes Beispiel ist? Der Typ des ersten Arguments ( b ) ist double[] , während es in der Funktionsdefinition T[] ist. Daher sieht es so aus, dass T double sein sollte. Der Typ des dritten Arguments ( 40 ) ist jedoch int . Daher scheint T int zu sein. Daher der Fehler.

Wenn 40 in 40.0 geändert wird, funktioniert es. Ein anderer Ansatz besteht darin, zwei verschiedene -Typen in der Schablonendeklaration zu verwenden:

%Vor%

Beachten Sie, dass ich s explizit auf T setzen musste, da das letzte Beispiel sonst einen Bruchteil verliert.

Diese Lösung funktioniert jedoch immer noch nicht für sumArray(a,3,10.1) , da sie 10.1 auf int ausgibt. Wenn dies also ein möglicher Anwendungsfall ist, ist eine genauere Behandlung erforderlich. Ein voll funktionsfähiges Beispiel mit C ++ 11 Funktionen könnte wie folgt aussehen:

%Vor%

Eine weitere mögliche Verbesserung für diese Template-Funktion ist die automatische Ableitung der Array-Größe, siehe TartanLlamas Antwort.

    
Petr 27.08.2015, 14:18
quelle
4
%Vor%

Der Typ von 40 ist int , aber der Typ von b ist double[3] . Wenn Sie diese als Argumente übergeben, erhält der Compiler Konflikte mit Typen für T .

Eine einfache Möglichkeit, dies zu beheben, besteht darin, einfach eine double :

zu übergeben %Vor%

Es wäre jedoch wahrscheinlich besser, wenn Sie Conversions auf der Aufrufseite zulassen, indem Sie einen weiteren Vorlagenparameter hinzufügen. Sie können auch eine hinzufügen, um die Größe des Arrays für Sie abzuleiten, so dass Sie es nicht explizit übergeben müssen:

%Vor%

Der Parameter U wird standardmäßig auf T gesetzt, um den Standardwert für s zu unterstützen. Beachten Sie, dass wir, um die Größe des Arrays abzuleiten, einen Verweis darauf übergeben müssen, anstatt den Wert zu überschreiten, was dazu führen würde, dass es zu einem Zeiger wird.

Der Aufruf sieht jetzt so aus:

%Vor%

Live-Demo

    
TartanLlama 27.08.2015 14:24
quelle
3

In

%Vor%

Beide (ableitbar) T sollten übereinstimmen.

In sumArray(b, 3, 40) ist es double für die erste und int für die zweite.

Es gibt mehrere Möglichkeiten, das Problem zu beheben

  • Rufen Sie auf der Aufrufseite sumArray(b, 3, 40.0) oder sumArray<double>(b, 3, 40);

  • auf
  • Verwenden Sie zusätzlichen Parameter:

    %Vor%

    Der Rückgabetyp kann abhängig von Ihren Anforderungen T , S oder decltype(arr[0] + s) sein.

  • mache einen Parameter nicht nachvollziehbar:

    %Vor%
Jarod42 27.08.2015 14:24
quelle
2

Sollte

sein %Vor%

Also wird T auf double abgeleitet. In deinem Code ist int .

    
ForEveR 27.08.2015 14:18
quelle
1

Eine andere Möglichkeit, wenn der Abzug fehlschlägt, ist, dem Compiler explizit mitzuteilen, was Sie meinen:

%Vor%     
Alan Stokes 27.08.2015 14:27
quelle
0

Der Compiler weiß nicht, ob T int oder double sein soll.

Sie können Folgendes tun, um die höchste Genauigkeit der übergebenen Typen zu erhalten:

%Vor%

Die Funktion, die Sie schreiben, existiert jedoch bereits. Es ist std::accumulate :

%Vor%     
JohnB 27.08.2015 14:43
quelle
-1

Vorlagen akzeptieren nur einen Datentyp. Wenn Sie beispielsweise ein Array von double senden, leitet die Laufzeit Folgendes ab:

Vorlage = doppelt []

damit er jedesmal, wenn er es sieht, eine Reihe von Doppelgängern erwartet.

sumArray(b,3,40) übergibt "b" (was ein Array von Doubles ist), aber dann übergeben Sie "40", was die Laufzeit nicht implizit in double konvertieren kann.

Also der Code

%Vor%

funktioniert

    
Thomas Pelletier 27.08.2015 14:26
quelle

Tags und Links