This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: problems using blitz::TinyVector as key for map


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.




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]