I was trying to come up with a neat STL-heavy response to this thread
about multimaps: http://groups.google.com/group/comp....e6796296b79797
My implementation involved using unique_copy to uniquify the set of
keys. However, the compiler (gcc 4.0.2) complains because it's trying
to (internally) use
std::pair<const int, int> & std::pair<const int,
int>::operator=(std::pair<const int,int> const&)
which it has synthesized. The code is as follows:
#include <map>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int, int> value;
bool cmp(value const& lhs, value const& rhs)
{
return lhs.first == rhs.first;
}
int main()
{
typedef map<int, int> m_t;
m_t m;
vector<value> v;
copy(m.begin(),
m.end(),
back_inserter<vector<value> >(v));
unique_copy(m.begin(),
m.end(),
back_inserter<vector<value> >(v),
cmp);
return EXIT_SUCCESS;
}
Note that the call to copy() proceeds without problem. I can
understand why the map holds std::pair<const int, int> rather than
std::pair<int, int>, but I don't see why it would need to assign to a
value of that type to do unique_copy. Especially because copy() works
just fine... anyone got an idea here?
Luke 8 1636
Luke Meyers wrote: I was trying to come up with a neat STL-heavy response to this thread about multimaps:
http://groups.google.com/group/comp....e6796296b79797
My implementation involved using unique_copy to uniquify the set of keys. However, the compiler (gcc 4.0.2) complains because it's trying to (internally) use
std::pair<const int, int> & std::pair<const int, int>::operator=(std::pair<const int,int> const&)
which it has synthesized. The code is as follows:
#include <map> #include <algorithm> #include <vector>
using namespace std;
typedef pair<int, int> value;
bool cmp(value const& lhs, value const& rhs) { return lhs.first == rhs.first; }
int main() { typedef map<int, int> m_t; m_t m;
vector<value> v;
copy(m.begin(), m.end(), back_inserter<vector<value> >(v));
unique_copy(m.begin(), m.end(), back_inserter<vector<value> >(v), cmp);
return EXIT_SUCCESS; }
Note that the call to copy() proceeds without problem. I can understand why the map holds std::pair<const int, int> rather than std::pair<int, int>, but I don't see why it would need to assign to a value of that type to do unique_copy. Especially because copy() works just fine... anyone got an idea here?
A look at the unique_copy implementation gives the clue. I am using g++
3.4.2 and here is how it looks
template<typename _InputIterator, typename _OutputIterator,
typename _BinaryPredicate>
_OutputIterator
__unique_copy(_InputIterator __first, _InputIterator __last,
_OutputIterator __result,
_BinaryPredicate __binary_pred,
output_iterator_tag)
{
// concept requirements -- iterators already checked
__glibcxx_function_requires(_BinaryPredicateConcep t<_BinaryPredicate,
typename iterator_traits<_InputIterator>::value_type,
typename iterator_traits<_InputIterator>::value_type>)
typename iterator_traits<_InputIterator>::value_type __value =
*__first;
*__result = __value;
while (++__first != __last)
if (!__binary_pred(__value, *__first))
{
__value = *__first;
*++__result = __value;
}
return ++__result;
}
The offending line is
__value = *__first;
in the inner loop which tries to assign to a variable of type
InputIterator::value_type. That fails as its a std::pair<const int,
int> whose *first* is *const int*.
Ram
Ram wrote: typename iterator_traits<_InputIterator>::value_type __value = *__first; *__result = __value; while (++__first != __last) if (!__binary_pred(__value, *__first)) { __value = *__first; *++__result = __value; }
The offending line is
__value = *__first;
in the inner loop which tries to assign to a variable of type InputIterator::value_type. That fails as its a std::pair<const int, int> whose *first* is *const int*.
Is this correct, though? It strikes me as an irritating and
unnecessary restriction, and while I'm loath to suggest that the gcc
STL implementation is wrong, I find nothing more plausible. I believe
it's correct for map to store pair<const int, int>. It seems like
unique_copy should be able to operate within the constraint of a
non-assignable value type, so long as that type is copy-constructible.
It may not be as efficient, but that could perhaps be addressed by
template specialization. Am I missing something here?
Luke
Luke Meyers wrote: I was trying to come up with a neat STL-heavy response to this thread about multimaps:
http://groups.google.com/group/comp....e6796296b79797 My implementation involved using unique_copy to uniquify the set of keys. However, the compiler (gcc 4.0.2) complains because it's trying to (internally) use
std::pair<const int, int> & std::pair<const int, int>::operator=(std::pair<const int,int> const&)
which it has synthesized. The code is as follows:
#include <map> #include <algorithm> #include <vector>
using namespace std;
typedef pair<int, int> value;
bool cmp(value const& lhs, value const& rhs) { return lhs.first == rhs.first; }
int main() { typedef map<int, int> m_t; m_t m;
vector<value> v;
copy(m.begin(), m.end(), back_inserter<vector<value> >(v));
unique_copy(m.begin(), m.end(), back_inserter<vector<value> >(v), cmp);
return EXIT_SUCCESS; }
Note that the call to copy() proceeds without problem. I can understand why the map holds std::pair<const int, int> rather than std::pair<int, int>, but I don't see why it would need to assign to a value of that type to do unique_copy. Especially because copy() works just fine... anyone got an idea here?
I had a look at the g++ implementation of unique_copy. Apparently, it uses a
variable of type iterator_traits<InIter>::value_type to keep track of runs
of equal elements. This is reasonable since input iterators have very weak
guarantees. This variable is updated using assignment. That is where the
error message comes from.
Here is a draft for a less restrictive unique_copy. It only uses
initialization of the variable:
template < typename InIter, typename OutIter, typename BinPred >
OutIter unique_copy ( InIter from, InIter to, OutIter where, BinPred eq ) {
typedef typename std::iterator_traits<InIter>::value_type value_type;
while ( from != to ) {
value_type last_value = *from++;
*where++ = last_value;
//skip loop:
while ( ( from != to ) && eq( last_value, *from ) ) {
++from;
}
}
return ( where );
}
Warning, this is totally untested code.
Also, I am not sure whether the g++ STL is in error: unique_copy is listed
under the modifying sequence operations, but the effects section for that
algorithm does not list any modification of the input sequence. I think
that [25/5] should then imply that the value_type is not supposed to be
modifyable.
Best
Kai-Uwe Bux
> > typename iterator_traits<_InputIterator>::value_type __value = *__first; *__result = __value; while (++__first != __last) if (!__binary_pred(__value, *__first)) { __value = *__first; *++__result = __value; }
The offending line is
__value = *__first;
in the inner loop which tries to assign to a variable of type InputIterator::value_type. That fails as its a std::pair<const int, int> whose *first* is *const int*.
Is this correct, though? It strikes me as an irritating and unnecessary restriction, and while I'm loath to suggest that the gcc STL implementation is wrong, I find nothing more plausible. I believe it's correct for map to store pair<const int, int>. It seems like unique_copy should be able to operate within the constraint of a non-assignable value type, so long as that type is copy-constructible. It may not be as efficient, but that could perhaps be addressed by template specialization. Am I missing something here?
I too wouldn't like to suggest that the implementation is wrong. But
its possible for the implementation to be less restrictive (to be able
to work with non-assignable value type). Instead of saving the values
one could save the iterator position for doing comparisons. Here's the
modified code (original commented out)-
// typename iterator_traits<_InputIterator>::value_type __value =
*__first;
_InputIterator __previous = __first;
// *__result = __value;
*__result = *__previous;
while (++__first != __last) {
// if (!__binary_pred(__value, *__first))
if (!__binary_pred(*__previous, *__first))
{
// __value = *__first;
__previous = __first;
// *++__result = __value;
*++__result = *__previous;
}
}
That puts the requirement of _InputIterator to be assignable though.
Not sure whether this might be a restriction. Also Kai-Uwe Bux
suggested an alternate implementation. Time to raise a bug-report with
g++ maintainers? :-)
Ram ra********@gmail.com wrote: > typename iterator_traits<_InputIterator>::value_type __value = > *__first; > *__result = __value; > while (++__first != __last) > if (!__binary_pred(__value, *__first)) > { > __value = *__first; > *++__result = __value; > } > > The offending line is > > __value = *__first; > > in the inner loop which tries to assign to a variable of type > InputIterator::value_type. That fails as its a std::pair<const int, > int> whose *first* is *const int*. Is this correct, though? It strikes me as an irritating and unnecessary restriction, and while I'm loath to suggest that the gcc STL implementation is wrong, I find nothing more plausible. I believe it's correct for map to store pair<const int, int>. It seems like unique_copy should be able to operate within the constraint of a non-assignable value type, so long as that type is copy-constructible. It may not be as efficient, but that could perhaps be addressed by template specialization. Am I missing something here?
I too wouldn't like to suggest that the implementation is wrong. But its possible for the implementation to be less restrictive (to be able to work with non-assignable value type). Instead of saving the values one could save the iterator position for doing comparisons. Here's the modified code (original commented out)-
_InputIterator __previous = __first; *__result = *__previous; while (++__first != __last) { if (!__binary_pred(*__previous, *__first))
This will *not* work: __previous is invalidated by incrementing __first. The
postconditions for ++r on input iterator are stated as follows [24, Table
72]:
++r X&
pre: r is dereferenceable.
post: r is dereferenceable or r is past-the-end.
post: any copies of the previous value of r are no longer
required either to be dereferenceable or to be in the domain of ==
{ __previous = __first; *++__result = *__previous; } }
That puts the requirement of _InputIterator to be assignable though. Not sure whether this might be a restriction.
No, input iterators are assignable. However, you cannot use stored values of
an iterator that has been incremented for dereferencing.
Best
Kai-Uwe Bux
[...] _InputIterator __previous = __first; *__result = *__previous; while (++__first != __last) { if (!__binary_pred(*__previous, *__first))
This will *not* work: __previous is invalidated by incrementing __first. The postconditions for ++r on input iterator are stated as follows [24, Table 72]:
++r X& pre: r is dereferenceable. post: r is dereferenceable or r is past-the-end. post: any copies of the previous value of r are no longer required either to be dereferenceable or to be in the domain of ==
{ __previous = __first; *++__result = *__previous; } }
That puts the requirement of _InputIterator to be assignable though. Not sure whether this might be a restriction.
No, input iterators are assignable. However, you cannot use stored values of an iterator that has been incremented for dereferencing.
Oh yes. It won't work with iterators which wrap an input stream for
example..
In article <11**********************@j33g2000cwa.googlegroups .com>,
"Luke Meyers" <n.***********@gmail.com> wrote: Is this correct, though? It strikes me as an irritating and unnecessary restriction, and while I'm loath to suggest that the gcc STL implementation is wrong, I find nothing more plausible. I believe it's correct for map to store pair<const int, int>. It seems like unique_copy should be able to operate within the constraint of a non-assignable value type, so long as that type is copy-constructible. It may not be as efficient, but that could perhaps be addressed by template specialization. Am I missing something here?
The standard is in error. I've attempted to correct it (twice now): http://www.open-std.org/jtc1/sc22/wg...ctive.html#538
The corrected standard will have the effect of making gcc incorrect, and
your example code conforming. However gcc has already been corrected
(not sure which release) so that it will be conforming by the time this
defect report becomes normative.
-Howard
Howard Hinnant wrote: In article <11**********************@j33g2000cwa.googlegroups .com>, "Luke Meyers" <n.***********@gmail.com> wrote: Am I missing something here? The standard is in error.
Ah, sweet vindication!
I've attempted to correct it (twice now):
http://www.open-std.org/jtc1/sc22/wg...ctive.html#538
Thank you very much for providing this response, and for Fighting the
Good Fight.
The corrected standard will have the effect of making gcc incorrect, and your example code conforming. However gcc has already been corrected (not sure which release) so that it will be conforming by the time this defect report becomes normative.
Fantastic. I'll see if a gcc update does the trick.
Cheers,
Luke This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Richard Hayden |
last post by:
Hi,
I understand such pointers as 'const int* const ip' and 'const int*
ip' etc., but I'm getting confused when seeing things like 'const int*
const* ip' (i.e. with two or more asterisks)....
|
by: Trevor Lango |
last post by:
I want to be able to cast away the constness of a private member variable in
a member function of a class.
I have the private data member declared as follows:
const double x;
I have an...
|
by: Srini |
last post by:
Hello all,
I was just wondering about this. A const member function guarantees
constness of the object within the function body. But there's no way
for a member function to guarantee the...
|
by: Olav |
last post by:
Hi
I wonder if it is possible to have templates expand based on constness,
something like:
template<typename A, typename B>copy( A &a, B &b);
becoming:
copy( const class AClass &a, class...
|
by: Vijayakrishna Pondala |
last post by:
Hi,
We are using the following error randomly, when accessing a webservice
method/servlet hosted on JBoss application server:
The underlying connection was closed: An unexpected error occurred...
|
by: PengYu.UT |
last post by:
In the following program, I want an iterator contain pointer pointing
to constant object not const pointer. If it is possible would you
please let me know how to do it?
#include...
|
by: Laurent Deniau |
last post by:
I am looking for the "cleanest" way to cast away the constness of a
pointee in C89, something like const_cast<T*>() in C++. Actually, I am
using:
#define CONST_CAST(typename,value) \
(((union {...
|
by: bintom |
last post by:
I ran the following simple code in C++ and got unexpected results:
float f = 139.4;
cout << f;
Output:
139.399994;
|
by: Javier |
last post by:
Hello,
I have some cuestions about constness with standard containers and
pointers.
Supose I have a list of pointers to some class B:
std::list< B * list;
I have readed that constness in...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |