5

Wenn ich eine generische Struktur/Klasse:Wie man zwei Schablonentypen für arithmitische Operationen wie eingebaute Typen fördert?

template<typename T> 
struct Container 
{ 
    T value; 
    Container(const Value& value) : value(value) { } 
}; 

Und ich möchte eine Operation auf zwei von ihnen auszuführen:

template<typename T, typename U> 
Container<T> operator+(const Container<T>& lhs, const Container<U>& rhs) 
{ 
    return Container<T>(lhs.value + rhs.value); 
} 

Das Problem ist, dass, wenn lhs ist vom Typ Container<int> und rhs ist vom Typ Container<float>, dann bekomme ich eine Container<int> zurück. Aber wenn ich auto result = 2 + 2.0f tun würde, dann würde result vom Typ float. Daher ist das Verhalten zwischen integrierten Typen und benutzerdefinierten Typen inkonsistent.

Also wie würde ich die operator+ Überladung nehmen und es Container<float> zurückgeben, ähnlich wie C++ arithmetische Förderung mit eingebauten Typen behandelt?

+0

Können Sie verwenden C++ 11? –

+0

@PiotrSkotnicki Ja. – Therhang

Antwort

5

Sofern Sie einen der beiden Typen des Templates verwenden, riskieren Sie, dass das Ergebnis der Summe umgewandelt wird. Wenn Sie beispielsweise versehentlich int als Zieltyp wählen, obwohl die Summe in float resultiert, wird sie auf den ausgewählten Typ reduziert.

Wie dem auch sei, beginnend mit 11 C++, Sie con auf der decltype Spezifizierer verlassen, wie im Beispiel oben (oder zumindest kann man das tun, wenn Container::T und Container::U gibt Typen, für die der + Operator definiert ist).

Ich habe auch die auto Spezifikation als Rückgabewert für die operator+ verwendet, denn es steht ab C++ 14 zur Verfügung und es ist wirklich sehr nützlich.

Es folgt dem Arbeitsbeispiel oben erwähnt:

#include <iostream> 
#include <vector> 

template<typename T> 
struct Container 
{ 
    T value; 
    Container(const T& value) : value(value) { } 
}; 

template<typename T, typename U> 
auto operator+(const Container<T>& lhs, const Container<U>& rhs) 
{ 
    return Container<decltype(lhs.value+rhs.value)>{lhs.value + rhs.value}; 
} 

int main() 
{ 
    Container<int> c1{1}; 
    Container<float> c2{0.5}; 
    std::cout << (c1+c2).value << std::endl; 
} 
+1

Sieht gut aus. Sie können es lesbarer machen mit einer 'make_container'-Hilfsfunktion, die das Template-Argument ableiten lässt:' return make_container (lhs.value + rhs.value); ' – hvd

+0

guten Punkt, ich würde es als Hausaufgabe belassen ...: -) – skypjack

+0

Gibt es zusätzliche Laufzeitkosten, die durch den Vorgang im 'decltype' hinzugefügt werden? Wäre es besser, wenn ich das Ergebnis in einer temporären 'auto' -Variablen speichern würde und einfach so etwas wie' return Container (result); '? – Therhang

Verwandte Themen