|
Boost Users : |
From: Zeljko Vrba (zvrba_at_[hidden])
Date: 2008-08-22 02:19:45
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#id2903300
>
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;
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net