operator == nicht gefunden
-
Hallo,
was muss ich tun, damit bei folgendem Code der operator == gefunden wird? Warum wird er nicht gefunden?#include <iostream> template<typename T> class BinaryTree { public: class ConstIterator { public: ConstIterator(BinaryTree const& tree); private: template<typename> friend bool operator == (ConstIterator const&, ConstIterator const&); BinaryTree const* tree_; }; ConstIterator Iterator() const; }; template<typename T> BinaryTree<T>::ConstIterator::ConstIterator(BinaryTree const& tree) : tree_(&tree) { } template<typename T> typename BinaryTree<T>::ConstIterator BinaryTree<T>::Iterator() const { return ConstIterator(*this); } template<typename T> bool operator == (typename BinaryTree<T>::ConstIterator const& lhs, typename BinaryTree<T>::ConstIterator const& rhs) { return lhs.tree_ == rhs.tree_; } int main() { typedef BinaryTree<int> Tree; Tree tree; std::cout << (tree.Iterator() == tree.Iterator()) << std::endl; return 0; }Meldung:
gcc-4.5.4 schrieb:
test.cpp: In function ‘int main()’:
test.cpp:46:50: error: no match for ‘operator==’ in ‘tree.BinaryTree<T>::Iterator [with T = int]() == tree.BinaryTree<T>::Iterator [with T = int]()’Danke!
MfG
unwissender
-
template<typename T> class BinaryTree { ... class ConstIterator { ... template<typename> friend bool operator == (ConstIterator const&, ConstIterator const&); // der Templateparameter ist überflüssig und ein Problem: er kann nicht deduziert werden ... template<typename T> // Templateparameter kann nicht deduziert werden bool operator == (typename BinaryTree<T>::ConstIterator const& lhs, typename BinaryTree<T>::ConstIterator const& rhs);Die einfachste Lösung besteht in eine inline-friend-Definition einer normalen Funktion
template<typename T> class BinaryTree { ... class ConstIterator { ... friend bool operator == (ConstIterator const&, ConstIterator const&) { ... }Andere Möglichkeiten (die einen deduzierbaren Templateparameter zur Folge haben) wären:
- den Vergleichsoperator T allgemeiner fassen und per Predikat und SFINAE auf ConstIterator einzuschränken
- ConstIterator nicht als Member von BinaryTree zu definieren
-
Danke für deine Antwort.
camper schrieb:
Andere Möglichkeiten (die einen deduzierbaren Templateparameter zur Folge haben) wären:
- den Vergleichsoperator T allgemeiner fassen und per Predikat und SFINAE auf ConstIterator einzuschränkenKannst du ein kleines Beispiel dazu geben? Also T allgemeiner fassen ist klar, aber wie genau stellst du dir das mit dem Predikat vor?
Danke!
-
unwissender_ schrieb:
Danke für deine Antwort.
camper schrieb:
Andere Möglichkeiten (die einen deduzierbaren Templateparameter zur Folge haben) wären:
- den Vergleichsoperator T allgemeiner fassen und per Predikat und SFINAE auf ConstIterator einzuschränkenKannst du ein kleines Beispiel dazu geben? Also T allgemeiner fassen ist klar, aber wie genau stellst du dir das mit dem Predikat vor?
Danke!
z.B.
#include <type_traits> #include <utility> template<typename T> class BinaryTree { public: class ConstIterator { public: typedef T value_type; ConstIterator(BinaryTree const& tree); private: template<typename U> friend typename std::enable_if<std::is_same<U, typename Binary_Tree<typename U::value_type>::ConstIterator>::value, bool>::type operator == (const U& lhs, const U& rhs); BinaryTree const* tree_; }; ConstIterator Iterator() const; }; template<typename U> typename std::enable_if<std::is_same<U, typename Binary_Tree<typename U::value_type>::ConstIterator>::value, bool>::type operator == (const U& lhs, const U& rhs) { return lhs.tree_ == rhs.tree_; }
-
Eine andere Möglichkeit ist die Verallgemeinerung der Parameter verbunden mit einer eingeschränkten Sichtbarkeit (per ADL), z.B.
namespace secret { struct secret_base {}; template <typename T> bool operator==(const T& lhs, const T& rhs) { return lhs.tree_ == rhs.tree_; } } template<typename T> class BinaryTree { public: class ConstIterator : secret::secret_base // secret ist damit assozierter Namensraum { public: ConstIterator(BinaryTree const& tree); private: friend bool secret::operator==<>(const ConstIterator& lhs, const ConstIterator& rhs); BinaryTree const* tree_; }; ConstIterator Iterator() const; };
-
Interessant. Danke fuer die Ausfuehrungen! Aber bei der Auswahl belasse ich den operator == einfach als Member-Funktion, sieht zwar ein bisschen komisch aus, ist aber imo noch besser als die Alternativen
