Hi!
You are right. The “boost::” in front of the macro is of course wrong. Here is the version which has only the last error.
#include <iostream>
#include <boost/foreach.hpp>
#include "TObjArray.h"
#include "TVector3.h"
//using namespace ROOT;
TIterCategory<TObjArray> range_begin( TObjArray & x ) {
return TIterCategory<TObjArray>(&x).Begin();
}
TIterCategory<TObjArray> range_end( TObjArray & x ) {
return TIterCategory<TObjArray>(&x).End();
}
/*
TIterCategory<TObjArray> range_begin( TObjArray const & x ) {
return TIterCategory<TObjArray>(&x).Begin();
}
TIterCategory<TObjArray> range_end( TObjArray const & x ) {
return TIterCategory<TObjArray>(&x).End();
}
*/
bool operator==(const TIterCategory<TObjArray>& lhs, const TIterCategory<TObjArray>& rhs) {
return !(lhs != rhs);
}
namespace boost
{
// specialize range_mutable_iterator and range_const_iterator in namespace boost
template<>
struct range_mutable_iterator<TObjArray >
{
typedef TIterCategory<TObjArray> type;
};
template<>
struct range_const_iterator<TObjArray >
{
typedef TIterCategory<TObjArray> type;
};
}
int main() {
TObjArray objArray;
objArray.Add(new TVector3(1,2,3));
BOOST_FOREACH(const TObject* s, objArray) {
std::cout << s << '\n';
}
}
$ g++ -Wall `root-config --libs --cflags` -I/usr/include/boost foreach_TObjArray.cc -o foreach_TObjArray
In file included from foreach_TObjArray.cc:2:
/usr/local/include/boost/foreach.hpp: In function ‘typename boost::foreach_detail_::foreach_reference<T, C>::type boost::foreach_detail_::deref(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<T, C>*) [with T = TObjArray, C = mpl_::bool_<false>]’:
foreach_TObjArray.cc:66: instantiated from here
/usr/local/include/boost/foreach.hpp:750: error: invalid initialization of non-const reference of type ‘const TObject*&’ from a temporary of type ‘TObject*’
/usr/local/include/boost/foreach.hpp:750
template<typename T, typename C>
inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type
deref(auto_any_t cur, type2type<T, C> *)
{
typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t;
return *auto_any_cast<iter_t, boost::mpl::false_>(cur);
}
(the return is line 750)
The preprocessor (g++ -E …) turns the macro into:
int main() {
TObjArray objArray;
objArray.Add(new TVector3(1,2,3));
if (boost::foreach_detail_::auto_any_t _foreach_col66 = boost::foreach_detail_::contain( (objArray) , (true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(objArray)) , (true ? 0 : boost::foreach_detail_::is_rvalue_( (true ? boost::foreach_detail_::make_probe(objArray) : (objArray)), 0))) , boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(objArray) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(objArray) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else if (boost::foreach_detail_::auto_any_t _foreach_cur66 = boost::foreach_detail_::begin( _foreach_col66 , (true ? 0 : boost::foreach_detail_::encode_type(objArray, boost::foreach_detail_::is_const_(objArray))) , (true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(objArray)) , (true ? 0 : boost::foreach_detail_::is_rvalue_( (true ? boost::foreach_detail_::make_probe(objArray) : (objArray)), 0))) , boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(objArray) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(objArray) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else if (boost::foreach_detail_::auto_any_t _foreach_end66 = boost::foreach_detail_::end( _foreach_col66 , (true ? 0 : boost::foreach_detail_::encode_type(objArray, boost::foreach_detail_::is_const_(objArray))) , (true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(objArray)) , (true ? 0 : boost::foreach_detail_::is_rvalue_( (true ? boost::foreach_detail_::make_probe(objArray) : (objArray)), 0))) , boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(objArray) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(objArray) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else for (bool _foreach_continue66 = true; _foreach_continue66 && !boost::foreach_detail_::done( _foreach_cur66 , _foreach_end66 , (true ? 0 : boost::foreach_detail_::encode_type(objArray, boost::foreach_detail_::is_const_(objArray)))); _foreach_continue66 ? boost::foreach_detail_::next( _foreach_cur66 , (true ? 0 : boost::foreach_detail_::encode_type(objArray, boost::foreach_detail_::is_const_(objArray)))) : (void)0) if (boost::foreach_detail_::set_false(_foreach_continue66)) {} else for (const TObject* s = boost::foreach_detail_::deref( _foreach_cur66 , (true ? 0 : boost::foreach_detail_::encode_type(objArray, boost::foreach_detail_::is_const_(objArray)))); !_foreach_continue66; _foreach_continue66 = true) {
std::cout << s << '\n';
}
}
The error itself happens for code like this:
int* f() {
int a = 3;
return &a;
}
int main() {
const int*& rint = f();
}
I know this turns into an academic exercise. But I would like to solve the puzzle.
Thanks in advance,
Sebastian