Boost logo

Boost Users :

From: Manuel Holtgrewe (purestorm_at_[hidden])
Date: 2007-07-19 17:57:02


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 <boost/iterator/transform_iterator.hpp>

class plus_two : public std::unary_function<int, int> {
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_at_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_at_host:~/tmp> gcc-4.2.0 conflict.cpp
conflict.cpp: In function 'void inner(Pair) [with Pair =
std::pair<boost::transform_iterator<plus_two, int*,
boost::use_default, boost::use_default>,
boost::transform_iterator<plus_two, int*, boost::use_default,
boost::use_default> >]':
conflict.cpp:29: instantiated from 'void outer(InIterator,
InIterator) [with InIterator = boost::transform_iterator<plus_two,
int*, boost::use_default, boost::use_default>]'
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<boost::transform_iterator<plus_t
wo, int*, boost::use_default, boost::use_default> >*' to 'int*' in
initialization

== Intel C++ Compiler Output ==

user_at_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_at_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<plus_two, int *,
boost::use_default, boost::use_default>,
boost::transform_iterator<plus_two, int *, boost::use_default,
boost::use_default>>]" at line 29
             instantiation of "void outer(InIterator, InIterator)
[with InIterator=boost::transform_iterator<plus_two, int *,
boost::use_default, boost::use_default>]" at line 35

conflict.cpp(21): error: a value of type
"boost::detail::operator_brackets_proxy<boost::transform_iterator<plus_t
wo, int *, boost::use_default, boost::use_default>> *" 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<plus_two, int *,
boost::use_default, boost::use_default>,
boost::transform_iterator<plus_two, int *, boost::use_default,
boost::use_default>>]" at line 29
             instantiation of "void outer(InIterator, InIterator)
[with InIterator=boost::transform_iterator<plus_two, int *,
boost::use_default, boost::use_default>]" at line 35

compilation aborted for conflict.cpp (code 2)


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net