Topic: Question de-referencing iterator


Author: martelli@cadlab.it (Alex Martelli)
Date: 1996/11/09
Raw View
"Mark Fischer" <markf@starwave.com> writes:

>I am experiencing trouble dereferencing an iterator into a pair object.
>The compiler does not want to 'operator =' from *Iterator into pair.  Any
>ideas?  Thanks.

I think the compiler is right, and actually this has nothing to do
with iterators -- it's just that, according to the standard, it
seems to me that "struct pair" does NOT define an "operator="
(assignment operator).  The compiler will of course synthesize
one for it, with memberwise assignment -- but if one of the
members is _const_, then of course that member's assignment is
not going to work, is it?  And the iterator of a map dereferences
to a pair<const keytype, itemtype> -- note the "const".

Because of how templates work in general, there is no
relationship between instantiations of a template for
arguments that are classes with a relationship of some
sort to each other -- this includes one being the const
decorated version of the other (that's a good reason to
have _member_ templates, which I believe is in the
current draft standard but not widely implemented, but
I digress).  I.e., that you can assign an X to an Y does
NOT in any way, shape, or form, imply that you can assign
a mytemplate<X> to a mytemplate<Y>.  So, that you can
assign a "const X" to an "X", does not imply that you
can assign a "pair<const X,Y>" to a "pair<X,Y>" -- not
with a compiler-generated assignment operator, at least.

There are various possible solutions, but I think you'll
have to forego the assignment operator itself because it
needs to be a member of the assigned-to class, and you
can't really tamper with the template for struct pair.
Probably the slickest available solution is an inline
template function:

template <class A, class B, class C, class D>
inline void
assign_pair(pair<A,B>&lhs, const pair<C,D>&rhs)
{
    lhs.first=rhs.first; lhs.second=rhs.second;
}

I don't know if your compiler will be smart enough
to infer proper behaviour for a call to

 assign_pair(p, *itable);

where you now have, incorrectly,

 p = *itable;

but it is at least worth a try.  It works under
G++ 2.7, i.e., the following example...:


#include <map>
#include <iostream.h>

template <class A, class B, class C, class D>
inline void
assign_pair(pair<A,B>&lhs, const pair<C,D>&rhs)
{
    lhs.first=rhs.first; lhs.second=rhs.second;
}

int main()
{
    pair<const int, int> a(2,3);
    pair<int, int> b(4,5);

    cout << a.first << a.second << b.first << b.second << endl;

    // b = a;
    assign_pair(b,a);

    cout << a.first << a.second << b.first << b.second << endl;

    return 0;
}

will correctly run, emitting two lines "2345" and "2323",
while it will fail to compile if you uncomment the assigment.


Alex
--
DISCLAIMER: these are MY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it -- Phone: +39 (51) 597 313  [Fax: 597 120]
Cad.Lab S.p.A., v. Ronzani 7/29, 40033 Casalecchio (BO), Italia
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Mark Fischer" <markf@starwave.com>
Date: 1996/10/31
Raw View
I am experiencing trouble dereferencing an iterator into a pair object.
The compiler does not want to 'operator =' from *Iterator into pair.  Any
ideas?  Thanks.

// Test of map and iterator.  Place data in map and use iterator

#include <map>
#include <iterator>
#include <windows.h>

// disable MSVC42 256 byte debug limit warning
#pragma warning( disable : 4786 )

int WINAPI WinMain(HINSTANCE hInstance,
       HINSTANCE hPrevInstance,
       LPSTR lpCmdLine,
       int nCmdShow )
{
map <long , int, less<long>, allocator< int > > table;
map <long , int, less<long>, allocator< int > >::iterator itable;
pair < long, int > p;
int e1 = {1};

 table[100] = e1;
 itable = table.find(100);
 if (itable != table.end())
 {
// The following line produces the following error message from MSVC42:
// Error C2582: 'pair<long,struct Element>' : 'operator =' function is
unavailable
  p = *itable; // Error C2582; How do I dereference iterator itable into
pair?
 }
 return ( FALSE );
}

--
_Fish
markf@starwave.com


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: darin@goonsquad.spies.com (Darin Adler)
Date: 1996/11/01
Raw View
In article <01bbc66d$cf4633c0$69c469c6@markf>, "Mark Fischer"
<markf@starwave.com> wrote:

> I am experiencing trouble dereferencing an iterator into a pair object.
>
> #include <map>
> #include <iterator>
>
> [...]
>
> map <long , int, less<long>, allocator< int > > table;
> map <long , int, less<long>, allocator< int > >::iterator itable;
> pair < long, int > p;
> int e1 = {1};
>
>         table[100] = e1;
>         itable = table.find(100);
>         if (itable != table.end())
>         {
> // The following line produces the following error message from MSVC42:
> // Error C2582: 'pair<long,struct Element>' : 'operator =' function is
unavailable
>                 p = *itable;
> // How do I dereference iterator itable into pair?
>         }

I tried an equivalent non-Windows program with Metrowerks C++ (and the
Metrowerks Standard Library).

The error I got was:

"cannot convert 'pair<const long, int>' to 'pair<long, int>'"

Changing the declaration of p to 'pair<const long, int>' worked around the
problem.  I believe this is a bug in the Metrowerks C+ compiler.

Perhaps the MSVC problem is similar.  You might want to try the 'const
long' workaround to see if it has any effect.


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]