This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: problems using blitz::TinyVector as key for map
- From: Peter Doerfler <doerfler at techinfo dot rwth-aachen dot de>
- To: libstdc++ at gcc dot gnu dot org
- Cc: Faheem Mitha <faheem at email dot unc dot edu>
- Date: Fri, 07 Oct 2005 10:49:49 +0200
- Subject: Re: problems using blitz::TinyVector as key for map
- References: <Pine.LNX.4.62.0510070206280.20127@Chrestomanci>
Hi Faheem.
Comments below...
On Friday 07 October 2005 08:17, Faheem Mitha wrote:
> Hi,
>
> I'm having problems with using 'find' on a map whose key is a
> blitz::TinyVector<T, N>. See http://www.oonumerics.org/blitz/ for more
> information about the Blitz++ library.
>
> Can anyone tell me if I'm doing something wrong, or is this a bug?
>
> Thanks. Faheem.
>
> ******************************************************************
> g++ -o foo foo.cc
>
> $ ./foo
> 3 [ 50 50 49 ]
> 3 [ 0 0 0 ]
>
> ******************************************************************
> foo.cc
> ******************************************************************
> #include <iostream>
> #include <map>
> #include <blitz/array.h>
> #include <blitz/tinyvec-et.h>
>
> using std::map;
> using std::cout;
> using std::endl;
>
> namespace blitz
> {
> // Less operator (function object) for TinyVector.
> template<typename T, int N>
> class TinyVectorless
> {
> public:
> inline bool operator() (const blitz::TinyVector<T, N>& u, const
> blitz::TinyVector<T, N>& v) const
> {
> return blitz::all(u < v);
> }
> };
> }
>
What does blitz::all() do? Looks like operator<() is defined for TinyVector.
In that case you shouldn't need to make your own less since std::less just
calls operator<().
> int main()
> {
> map<blitz::TinyVector<int, 3>, int, blitz::TinyVectorless<int, 3> >
> dict;
> dict[blitz::TinyVector<int, 3>(50, 50, 49)] = 0;
> dict[blitz::TinyVector<int, 3>(60, 60, 60)] = 1;
> blitz::TinyVector<int, 3> x(2, 2, 1000);
> blitz::TinyVector<int, 3> y(2, 2, 2);
> cout << (dict.find(x))->first << endl;
> cout << (dict.find(y))->first << endl;
> return 0;
> }
You are dereferencing the end of the map because neither x nor y are contained
in dict. AFAIK dereferencing end() is undefined and could do anything. Dig
into stl_tree.h to figure out why you might be getting the results you see --
in case you care ;)
Anyway, you need to check whether your key was actually found, somewhere along
the lines of
typedef map<blitz::TinyVector<int, 3>, int, blitz::TinyVectorless<int, 3> >
dict_type;
typedef dict_type::iterator dict_iterator;
dict_iterator it = dict.find(x);
cout << (it!=dict.end() ? (*it).first : "not found") << endl;
Not tested since I'm not using blitz.
HTH,
Peter
PS: You might want to pick up a good book about using the STL like "Effective
STL" if you'll be using it more.