Verschiedene Typen mit std::find_if finden
-
Hi Leute,
ich hab grad nen Hänger.
Folgende Klasse existiert:
class Texture { private: std::tr1::shared_ptr<GLTXimage> img; std::string name; public: Texture(const std::string&, GLTXimage*); const std::string& getName() const; const std::tr1::shared_ptr<GLTXimage>& getTexture() const; };
Ich hab jetzt einen Vector(textures) aus Texturen und biete eine Methode
TextureContainer::const_iterator TextureContainer::get(const std::string& textureName) const { return std::find_if(this->textures.begin(), this->textures.end(), std::bind1st(EqualTextureByName(),textureName)); }
Jetzt wollte ich in dem Vector nach einer Texture suchen, die dem übergebenen Namen entspricht.
Der Comparator sieht aktuell so aus(ich weiß das es falsch ist, aber mir fiel nichts anderes ein)
struct EqualTextureByName : public std::binary_function<Texture,std::string,bool> { bool operator()(const Texture& t1, const std::string& t2) const { return t1.getName() == t2; } };
Könnt ihr mir auf die Sprünge helfen wie ich das bewerkstelligen kann, oder soll ich auf eine explizite Schleife ausweichen. Fänd ich schade, weil ich schon so viel Standardalgorithmen verwenden wollte wie möglich.
-
Vergiss
std::bind1st()
und Konsorten, die sind deprecated. Nimm stattdessenstd::bind()
oder direkt Lambdas. Manchmal schadet es auch nicht, eine traditionelle Schleife statt supergenerischen Funktoren zu verwenden...
-
Also ich würde gerne Lambdas verwenden, leider haben die Rechner in der Uni noch nicht den neuen Compiler und somit könnt ich vergessen dort zu entwickeln.
Mit std::bind würde es dann so aussehen:
TextureContainer::const_iterator TextureContainer::get(const std::string& textureName) const { using namespace std::tr1::placeholders; return std::find_if(this->textures.begin(), this->textures.end(), std::bind(EqualTextureByName(),_1,textureName)); }
Ist das richtig, ja? Was ich aber nicht ganz verstehe wie _1 und textureName da jetzt zusammen wirken?
-
Meinst du nicht, dass Texturen besser in einer std::map aufgehoben sind?
Wenn TextureContainer::get häufig genug aufgerufen wird und die Anzahl der Texturen groß genug ist, würde ich es mal ausprobieren und ein wenig profilen.
-
Meinst du nicht, dass Texturen besser in einem sortierten std::vector aufgehoben sind?
Wenn du auf einen sortierten Vector dann eine binary_search machst, ist das gleich schnell wie eine map. Und wenn er nicht sortiert ist, kannst du das bei get nachholen.
-
Ich bin entzückt von eueren zusätzlichen Ideen, jedoch hilft mir das nicht bei meinem Verständnisproblem zwischen dem Zusammenhang von _1 und textureNames.
Auf jeden Fall werde ich eure Ideen mit in Betracht ziehen meine Containerwahl eventuell nochmal zu überdenken.
-
Firefighter schrieb:
Verständnisproblem zwischen dem Zusammenhang von _1 und textureNames.
Es gibt gar keinen Zusammenhang. _1 bezieht sich auf den ersten Parameter, der dem Funktor übergeben wird, textureName wird direkt übergeben.
Kleines Besispiel:#include <memory> #include <iostream> void f(int a1, int a2, int a3) { std::cout << a1 << ' ' << a2 << ' ' << a3 << std::endl; } int main() { using namespace std::placeholders; auto fun1 = std::bind(f, 100, _2, _1); fun1(10, 20); // -> f(100, 20, 10) auto fun2 = std::bind(f, _1, _2, 100); fun2(10, 20); // f(10, 20, 100) auto fun3 = std::bind(f, _1, 100, 200); fun3(10); // f(10, 100, 200) }
Hoffe das ist jetzt klarer.