
On Fri, Aug 22, 2008 at 01:04:43PM +0800, Joel de Guzman wrote:
Read on Boost.Result of and the TR1 result_of conventions. http://www.boost.org/doc/libs/1_36_0/libs/utility/utility.htm http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html
It's not a function call. It's a function declarator. This is first discussed and put into use in the Boost.Function library: http://www.boost.org/doc/libs/1_36_0/doc/html/function/tutorial.html#id29033...
It would be nice to have those links together with the transform_view documentation, or in a separate section[*] if more components inside fusion use it. (I *did* look through table of contents before I asked on the list, but I couldn't find anything that looked like a matching section.) [*] Suggestion: put these links in the "References" section, and add a sentence after the example "See <hyperlink>references</hyperlink> for documentation about result conventions." (or something similar)
Are you sure the one above works? You need the result type, AFAICT.
Yes, I'm 100% sure that it works on Sun's C++ compiler, I have double-checked it right now (this is so bizzarre that I've even computed checksum before compilation just to make sure that I wasn't editing a wrong file). It spits out a long error message with gcc (but it compiles OK also with gcc when the result struct is in place). CC: Sun C++ 5.9 SunOS_i386 Patch 124864-03 2008/03/12 Below is a complete compileable program. I tried to combine transform_view with boost::lambda and bind to sort the vector of maps. While it compiles, the result of std::sort leaves an unchanged sequence! Here's the output: (8 7)(8 6)(1 4)(3 6)(3 2)(1 7)(4 3)(2 5) <- original std::vector<Map> 01 <- proof that tx(a) < tx(b) works (8 7)(8 6)(1 4)(3 6)(3 2)(1 7)(4 3)(2 5) <- "sorted" by custom functor (1 4)(1 7)(2 5)(3 2)(3 6)(4 3)(8 6)(8 7) <- sorted by using operator< The same thing happens also with gcc (after replacing #if 0 with #if 1 to make it compileable there). Compilation with Sun and gcc compilers: CC -I ~/COMPILE/boost_1_36_0 -library=stlport4 -m64 z.cc /usr/sfw/bin/gcc -m64 -I ~/COMPILE/boost_1_36_0 z.cc The Sun's compiler is indifferent to #if 0 / #if 1 -> compiles always gcc compiles the code only with #if 1 Anyway, I've figured out how to define operator< for fusion::pairs, so I'm going down that route. But I'm curious about the anomalous std::sort behavior. Why doesn't sort actually sort the std::vector (search for line marked XXX:)? Should I watch out for more similar pitfalls? === #include <iostream> #include <vector> #include <algorithm> #include <iterator> #include <boost/fusion/container/map/map.hpp> #include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/io.hpp> #include <boost/fusion/include/comparison.hpp> #include <boost/fusion/sequence/intrinsic/at_key.hpp> #include <boost/fusion/view/transform_view.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/type_traits/remove_reference.hpp> struct net; struct pin; namespace bf = boost::fusion; using std::cout; using std::endl; typedef bf::map<bf::pair<net, unsigned>, bf::pair<pin, unsigned> > Map; template<typename T> inline bool operator<(bf::pair<T, unsigned> a, bf::pair<T, unsigned> b) { return a.second < b.second; } struct Map2Pair { #if 0 template<typename T> struct result; template<typename T> struct result<Map2Pair(T)> { typedef typename boost::remove_reference<T>::type pair_type; typedef typename pair_type::second_type type; }; #endif template<typename T> typename T::second_type operator()(T t) const { return t.second; } }; typedef bf::transform_view<Map, Map2Pair> Pair; Pair tx(Map m) { return Pair(m, Map2Pair()); } int main() { using namespace boost::fusion; using namespace boost::lambda; using namespace boost; std::vector<Map> v; v.push_back(Map(8, 7)); v.push_back(Map(8, 6)); v.push_back(Map(1, 4)); v.push_back(Map(3, 6)); v.push_back(Map(3, 2)); v.push_back(Map(1, 7)); v.push_back(Map(4, 3)); v.push_back(Map(2, 5)); std::copy(v.begin(), v.end(), std::ostream_iterator<Map>(cout)); cout << endl; cout << (tx(v[0]) < tx(v[1])) << (tx(v[1]) < tx(v[0])) << endl; std::sort(v.begin(), v.end(), bind(&tx, _1) < bind(&tx, _2)); // XXX: no effect at all?! std::copy(v.begin(), v.end(), std::ostream_iterator<Map>(cout)); cout << endl; std::sort(v.begin(), v.end()); std::copy(v.begin(), v.end(), std::ostream_iterator<Map>(cout)); cout << endl; return 0; }