C++ STL fails to find comparator for nested class -
i expected code work, fails compile gcc. compile if lift inner class out.
#include <algorithm> template <typename t> struct outer { struct inner { int x; }; inner vec[3]; }; template <typename t> bool operator <(const typename outer<t>::inner& lhs, const typename outer<t>::inner& rhs) { return lhs.x < rhs.x; } int main() { outer<int> out; outer<int>::inner in; std::lower_bound(out.vec, out.vec + 3, in); }
gcc 4.4 has say:
... bits/stl_algo.h:2442: error: no match ‘operator<’ in ‘* __middle < __val’
gcc 4.7 prints lot more stuff, including above, ending this:
... bits/stl_algobase.h:957:4: note: couldn't deduce template parameter ‘t’
i'm willing believe it's not well-formed c++, why not?
the problem mentioned compiler couldn't deduce template parameter t
. because typename outer::inner nondeduced context context t.
when template parameter used in nondeduced context, it's not taken consideration template argument deduction. details @ section 14.8.2.4 of c++ standard (2003).
why? if specialize outer as:
template <> struct outer<int> { struct inner { double y; }; inner vec[3]; };
there no way compiler deduce if outer::inner should reference definition or previous one.
now, onto solutions. there couple of possible resolutions:
- move operator< inside inner , make friend function.
- define operator< inside inner m m. suggested.
- suggested johannes schaub - litb: derive inner crtp base parameterized inner. make parameter type crtp class , cast parameter reference derived inner class, type of given template argument deduce.
i tried out crtp approach since sounds cool!:
template <typename inner> struct base { }; template <typename t> struct outer { struct inner : base<inner> { t x; }; inner vec[3]; }; template <typename t> bool operator< (const base<t>& lhs, const base<t>& rhs) { return static_cast<const t&>(lhs).x < static_cast<const t&>(rhs).x; }
Comments
Post a Comment