Ich habe eine Reihe von boost :: shared_ptr, die ich nicht durch die geteilten Zeiger, sondern durch die Zeichenfolgen geordnet und uniqued werden möchte. Muss ich eine neue Vergleichsfunktion zur Verfügung stellen, um gemeinsame Zeiger zu erhalten und den Inhalt zu vergleichen, oder gibt es einen solchen Vergleicher, den ich benutzen kann?Std Set von boost :: shared_ptr <string>
4
A
Antwort
5
Das ist ziemlich spezifisch, so dass Sie wahrscheinlich einen benutzerdefinierten Komparator benötigen.
sollte diese Arbeit:
struct pointercompare
{
bool operator()(const boost::shared_ptr<std::string>& a, const boost::shared_ptr<std::string>& b)
{
return (*a)>(*b);
}
}
1
ich eine allgemeine Art und Weise schreiben würde, Prädikate und Iteratoren von Einwickeln, die Wert-Semantik auf jeden Zeiger artigen Besitzer zuordnet.
Dies wird dann völlig allgemein und wiederverwendbar.
Einfache Version hier
Bonus Code unten führt eine komplette Bibliothek für diese Art der Sache
#include <utility>
#include <boost/shared_ptr.hpp>
#include <vector>
#include <algorithm>
template<class Comp>
struct pointee
{
pointee(Comp comp = Comp()) : _comp(comp) {}
template<class APtr, class BPtr>
bool operator()(const APtr& a, const BPtr& b)
{
return _comp(*a, *b);
}
Comp _comp;
};
int main()
{
std::vector<boost::shared_ptr<int>> v;
std::sort(v.begin(), v.end(), pointee<std::less<>>());
std::sort(v.begin(), v.end(), pointee<std::greater<>>());
}
Für Bonuspunkte ...
#include <utility>
#include <boost/shared_ptr.hpp>
#include <vector>
#include <algorithm>
#include <functional>
template<class T, class X, class Y>
struct is_binary_op
{
template<class U> static auto test(U* p) -> decltype((*p)(std::declval<X>(), std::declval<Y>()), void(), std::true_type());
template<class U> static auto test(...) -> decltype(std::false_type());
static constexpr bool value = decltype(test((T*)0))::value;
};
template<class T, class X, class Y> static constexpr bool IsBinaryOp = is_binary_op<T, X, Y>::value;
template<class T, class X>
struct is_unary_op
{
template<class U> static auto test(U* p) -> decltype((*p)(std::declval<X>()), void(), std::true_type());
template<class U> static auto test(...) -> decltype(std::false_type());
static constexpr bool value = decltype(test((T*)0))::value;
};
template<class T, class X> static constexpr bool IsUnaryOp = is_unary_op<T, X>::value;
namespace detail {
template<class Comp>
struct pointee
{
pointee(Comp comp = Comp()) : _comp(comp) {}
template<
class APtr,
class BPtr
>
auto operator()(const APtr& a, const BPtr& b) const
-> std::enable_if_t<
IsBinaryOp<Comp, decltype(*a), decltype(*b)>
, bool>
{
return _comp(*a, *b);
}
template<
class APtr
>
auto operator()(const APtr& a) const
-> std::enable_if_t<
IsUnaryOp<Comp, decltype(*a)>
, bool>
{
return _comp(*a);
}
Comp _comp;
};
template<class Iter>
struct deref_iter : Iter
{
deref_iter(Iter iter) : Iter(iter) {}
auto& operator*() const {
return **static_cast<const Iter&>(*this);
}
};
}
template<class Pred>
auto pointee(Pred&& pred)
{
return detail::pointee<std::decay_t<Pred>>(std::forward<Pred>(pred));
}
template<class Iter>
auto deref_pointee(Iter&& iter)
{
return detail::deref_iter<std::decay_t<Iter>>(std::forward<Iter>(iter));
}
int main()
{
std::vector<boost::shared_ptr<int>> v;
// sort using the less predicate on the pointee
std::sort(v.begin(), v.end(), pointee(std::less<>()));
// sort using the greater predicate on the pointee
std::sort(v.begin(), v.end(), pointee(std::greater<>()));
// apply a unary predicate to every pointee
std::for_each(v.begin(), v.end(), pointee(std::logical_not<>()));
// transform the pointees by binding a binary predicate to a value and
// turning it into a unary predicate that adds 6
std::transform(v.begin(), v.end(),
deref_pointee(v.begin()),
pointee(std::bind(std::plus<>(), 6, std::placeholders::_1)));
}
Verwandte Themen
- 1. Verwenden von Boost Python & std :: shared_ptr
- 2. C++ 11 std :: shared_ptr + boost :: serialisierung
- 3. Boost :: shared_ptr <T> und boost :: shared_ptr <const T> teilen Sie die Referenzzahl?
- 4. Warum std :: shared_ptr <T> = std :: unique_ptr <T[]> Kompilierung, während std :: shared_ptr <T[]> = std :: unique_ptr <T[]> nicht?
- 5. shared_ptr in std :: tr1
- 6. Erstellen von boost :: thread mit einer std :: shared_ptr Objektinstanz
- 7. Wie funktioniert boost :: ~ shared_ptr?
- 8. boost :: shared_ptr Standardcontainer
- 9. Verwendung von std :: shared_ptr
- 10. NULL Zeiger mit boost :: shared_ptr?
- 11. Sollte ich boost :: ptr_vector <T> oder Vektor <boost :: shared_ptr <T>> verwenden?
- 12. Anpassen von std :: shared_ptr oder boost :: shared_ptr um eine Ausnahme auf NULL Dereferenz zu werfen
- 13. Casting Shared_ptr <T> Shared_ptr <void>
- 14. verschieben Besitz von std :: shared_ptr std :: unique_ptr
- 15. Verwechslung bezüglich boost :: shared_ptr
- 16. static_cast mit boost :: shared_ptr?
- 17. Eindeutige Kopie von std :: shared_ptr
- 18. Unterschiede zwischen tr1 :: shared_ptr und boost :: shared_ptr?
- 19. boost :: shared_ptr use_count
- 20. Boost Shared_Ptr Zuweisung
- 21. Wie die Verwendung von std :: bind mit std kombinieren :: shared_ptr
- 22. boost :: Variante <T> std :: string
- 23. Cast ‚this‘ std :: shared_ptr
- 24. Std :: shared_ptr und Vererbung
- 25. Initialisierung std :: shared_ptr <std::map<>> mit verspannten-init
- 26. Ist Boost shared_ptr <XX> thread-sicher?
- 27. Entsprechende Verwendung für boost :: shared_ptr?
- 28. Alternative zu std :: atomic_store (shared_ptr) für GCC <= 4.9?
- 29. Benutzerdefinierte Löscher für Boost shared_ptr
- 30. Boost initialisieren: shared_ptr zu NULL