Hi,
I have a problem using the Boost.Iterators library correctly. The
following minimal example does neither compile with GCC 4.2 nor with
a current ICC 10.0 version.
It seems that putting a boost::transform_iterator inside a pair makes
it impossible to retrieve its value again using std::iterator_traits.
I would welcome a proposal how to resolve the problem. I get the bug
when using transform_iterator together with the MCSTL (Multi Core
STL) and thus cannot change the internals. I would thus like to know
if and how I can make the following work without touching the inner()
and outer() functions themselves since I do not have the possibility
to change the library code itself.
Am I using boost::transform_iterator incorrectly?
Kind Regards,
Manuel
== File Source ==
#include <iostream>
#include <vector>
#include <functional>
#include
class plus_two : public std::unary_function {
public:
int operator()(int x) const {
return x + 2;
}
};
template <class Pair>
void inner(Pair pair) {
typedef typename Pair::first_type Iterator;
typedef typename std::iterator_traits<Iterator>::value_type T;
Pair p = pair;
T *x = &p.first[0];
(void)x;
}
template<class InIterator>
void outer(InIterator begin, InIterator end) {
typedef typename std::iterator_traits<InIterator>::value_type
ValueType;
inner(std::make_pair(begin, end));
}
int main(void) {
int in[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
outer( // broken
boost::make_transform_iterator(in, plus_two()),
boost::make_transform_iterator(in + 10, plus_two()));
outer(in, in+10); // working
return 0;
}
== GCC 4.2.0 Output ==
user@host:~/tmp> gcc-4.2.0 --version
gcc-4.2.0 (GCC) 4.2.0
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
user@host:~/tmp> gcc-4.2.0 conflict.cpp
conflict.cpp: In function 'void inner(Pair) [with Pair =
std::pair,
boost::transform_iterator >]':
conflict.cpp:29: instantiated from 'void outer(InIterator,
InIterator) [with InIterator = boost::transform_iterator]'
conflict.cpp:37: instantiated from here
conflict.cpp:21: warning: taking address of temporary
conflict.cpp:21: error: cannot convert
'boost::detail::operator_brackets_proxy >*' to 'int*' in
initialization
== Intel C++ Compiler Output ==
user@host:~/tmp> icc -V
Intel(R) C Compiler for applications running on Intel(R) 64, Version
10.0 Build 20070613 Package ID: l_cc_c_10.0.025
Copyright (C) 1985-2007 Intel Corporation. All rights reserved.
FOR NON-COMMERCIAL USE ONLY
user@host:~/tmp> icc conflict.cpp
conflict.cpp(21): warning #1563: taking the address of a temporary
T *x = &p.first[0];
^
detected during:
instantiation of "void inner(Pair) [with
Pair=std::pair,
boost::transform_iterator>]" at line 29
instantiation of "void outer(InIterator, InIterator)
[with InIterator=boost::transform_iterator]" at line 35
conflict.cpp(21): error: a value of type
"boost::detail::operator_brackets_proxy> *" cannot be used
to initialize an entity of type "T={int} *"
T *x = &p.first[0];
^
detected during:
instantiation of "void inner(Pair) [with
Pair=std::pair,
boost::transform_iterator>]" at line 29
instantiation of "void outer(InIterator, InIterator)
[with InIterator=boost::transform_iterator]" at line 35
compilation aborted for conflict.cpp (code 2)