Ich bin auf der Suche nach Ratschlägen zur Implementierung einer spezialisierten "max" -Funktion für einen benutzerdefinierten Datentyp, der auch mit skalaren Typen wie float
funktioniert. Der Datentyp, den ich schreibe, ist ein Wrapper für einen Vektor (schließlich ein SIMD-Vektor von vier Floats, kein std::vector
) und ich möchte eine max
-Funktion bereitstellen, um zwei Vektoren zu vergleichen und einen neuen Vektor zurückzugeben, der das Maximum jedes Elements ist . Dies ist anders als std::max
, die den Vergleichsoperator verwendet, aber das Konzept ist das gleiche. Das Problem ist, dass ich eine generische Funktion namens do_max(T x, T y)
habe, die max
auf die Eingänge anwendet. Ich brauche diese Funktion, um für beide Skalarschwimmereingaben (z. B. do_max<float>(0.1f, 0.2f)
) und meine Vektorklasse (z. B. do_max<MyVector>(v0, v1)
) zu arbeiten.C++ - Wie spezialisiere ich einen benutzerdefinierten Typ für std :: max ohne Vergleichsoperatoren zu überladen?
Beachten Sie, dass das Überladen von MyVectors Vergleichsoperatoren keine Option ist, da ich solche mit sehr unterschiedlichen SIMD-Intrinsics verwende: Sie erzeugen einen Ganzzahlvektor mit 1, 0, -1 für jeden Elementvergleich, anstatt einen booleschen Wert zurückzugeben Ergebnis.
Der Code, den ich unten nicht über kompilieren, wenn Sie die float f0 = ...
Zeilen aus kommentieren:
// compile with: g++ -std=c++11 max.cc -o max
#include <algorithm>
#include <vector>
class MyVector {
public:
MyVector(float x0, float x1, float x2, float x3) : storage_ { x0, x1, x2, x3 } {};
friend MyVector max(MyVector lhs, const MyVector & rhs);
private:
std::vector<float> storage_;
};
MyVector max(MyVector lhs, const MyVector & rhs) {
for (size_t i = 0; i < lhs.storage_.size(); ++i) {
lhs.storage_[i] = std::max(lhs.storage_[i], rhs.storage_[i]);
}
return lhs;
}
template<typename T>
T do_max(const T & x, const T & y) {
// if this is std::max then it won't compile for MyVector
return max(x, y);
}
int main(int argc, char * argv[]) {
MyVector v0 { 0.1, 0.2, 0.3, 0.4 };
MyVector v1 { 0.4, 0.3, 0.2, 0.1 };
MyVector v2 = do_max(v0, v1);
// Comment out the following line to successfully compile.
// However I'd like this to work for scalar types too:
float f0 = do_max(0.1f, 0.2f);
return 0;
}
ich ein Gefühl, das ich einen Weg brauchen habe, dass max
Funktion Entschlossenheit std::max
für skalare Typen zu machen, und mein Fach max
Freund-Funktion für den MyVector-Typ.
Wie definiere ich eine Max-Funktion, die auf diese Weise funktioniert? Ist es besser, std::max
zu vergessen und meine eigene Max-Funktion zu verwenden, die für MyVector
spezialisiert ist und auch Implementierung für skalare Typen wie float
bietet?
Der Hintergrund dafür ist, dass ich einen Datenpfad implementiere, von dem ich hoffe, dass er sowohl mit MyVector als auch mit skalaren Typen arbeitet (als parametrisierter Typ zur Kompilierungszeit). Ich habe bereits arithmetische Arbeiten, aber die Lösung für max
wird auch mit anderen Funktionen wie min
, exp
, pow
verwendet werden.
Danke, das funktioniert für mein Beispiel. – meowsqueak
Wissen Sie, warum dies fehlschlägt, wenn ich 'return max (x, y)' durch 'return max (x, y)' '? In diesem Fall sieht es so aus, als ob der Compiler es als Aufruf von 'std :: max (x, y) 'auflöst und mit einem ungültigen Operanden für den' <'Operator fehlschlägt, wenn' do_max 'instanziiert wird. Ich verstehe nicht, warum das Setzen des Typparameters explizit auf 'max' dieses Verhalten ändern würde. –
meowsqueak
Ihre Funktion ist keine Vorlage? max ist eine explizite Template-Instanziierung. –
MSalters