[multi-index] foreach supports breaks compilation

Hi, I realize this is not really a multi-index bug but after I updated from 1.47 to 1.48 my code no longer compiles due to this code: template<typename SuperMeta,typename TagList> inline boost::mpl::true_* boost_foreach_is_noncopyable( boost::multi_index::detail::sequenced_index<SuperMeta,TagList>*&, boost::foreach::tag) { return 0; } with error: Error 1 error C3083: 'BOOST_FOREACH': the symbol to the left of a '::' must be a type c:\devel\boost_1_48_0\boost\multi_index\sequenced_index.hpp 926 Error 2 error C2039: 'tag' : is not a member of 'boost' c:\devel\boost_1_48_0\boost\multi_index\sequenced_index.hpp 926 Error 3 error C2061: syntax error : identifier 'tag' c:\devel\boost_1_48_0\boost\multi_index\sequenced_index.hpp 926 (similar errors for other indices) this happens because as suggested in boost.foreach docs I have this earlier: #define foreach BOOST_FOREACH which (if I understand correctly) causes offending line to expand into: boost::BOOST_FOREACH::tag Is there anything easy I could do to fix this? btw, 1.47 version has no explicit section marked as /* Boost.Foreach compatibility */ yet I used BOOST_FOREACH macro on many indices all over the place. Regards, Simon

Hi Szymon, On 16 November 2011 10:40, Szymon Gatner <szymon.gatner@gmail.com> wrote:
I realize this is not really a multi-index bug but after I updated from 1.47 to 1.48 my code no longer compiles due to this code:
template<typename SuperMeta,typename TagList> inline boost::mpl::true_* boost_foreach_is_noncopyable( boost::multi_index::detail::sequenced_index<SuperMeta,TagList>*&, boost::foreach::tag) { return 0; }
...snip...
this happens because as suggested in boost.foreach docs I have this earlier:
#define foreach BOOST_FOREACH
I'm not certain whether there's anything under-the-hood of multi_index that could do this, but since #define foreach BOOST_FOREACH was just an example, and the user could define any PP token to expand as such, a change to multi_index could only ever work around that one example. I see a couple of possibilities for you: either #undef foreach before the above code, then #define it again afterwards, or use a name other than 'foreach'. Unfortunately (or not) this is just the way PP macros work, and why avoiding them is desirable - they are not namespaceable unlike real types & names. --rob -- Rob Desbois Eml: rob.desbois@gmail.com Blog: http://theotherbranch.wordpress.com/ Tel: 07946 705987 "I disapprove of what you say, but I’ll defend to the death your right to say it", Voltaire

I see a couple of possibilities for you: either #undef foreach before the above code, then #define it again afterwards, or use a name other than 'foreach'. Unfortunately (or not) this is just the way PP macros work, and why avoiding them is desirable - they are not namespaceable unlike real types & names.
Changing exiting code at this point is impossible. I might be forced to stay with multi-index version from 1.47. Cheers

Szymon Gatner wrote:
this happens because as suggested in boost.foreach docs I have this earlier:
#define foreach BOOST_FOREACH
which (if I understand correctly) causes offending line to expand into:
boost::BOOST_FOREACH::tag
Is there anything easy I could do to fix this?
Your problem depends on the ordering of header files and the macro definition: // OK #define foreach BOOST_FOREACH #include <boost/foreach.hpp> #include <boost/multi_index/hashed_index.hpp> // OK #include <boost/foreach.hpp> #include <boost/multi_index/hashed_index.hpp> #define foreach BOOST_FOREACH // Error #include <boost/foreach.hpp> #define foreach BOOST_FOREACH #include <boost/multi_index/hashed_index.hpp> If you can control the ordering, you can avoid the problem. But this solution is error prone. Fortunately, is_noncopyable and is_lightweight_proxy customization points seem to be only used in Boost.MultiIndex. So, I think, changing the name of namespace foreach is a viable solution. (Please note that this solution can break existing codes using is_noncopyable and is_lightweight_proxy customization points.) 1. Change namespace foreach --> namespace foreach_ foreach:: --> foreach_:: in boost/foreach.hpp and boost/foreach_fwd.hpp. 2. Change foreach:: --> foreach_:: in boost/multi_index/hashed_index.hpp boost/multi_index/ordered_index.hpp boost/multi_index/random_access_index.hpp boost/multi_index/sequenced_index.hpp (and, if you want, libs/foreach/test/noncopyable.cpp). Regards, Michel

If you can control the ordering, you can avoid the problem. But this solution is error prone.
Yup, can't really do this now.
Fortunately, is_noncopyable and is_lightweight_proxy customization points seem to be only used in Boost.MultiIndex. So, I think, changing the name of namespace foreach is a viable solution. (Please note that this solution can break existing codes using is_noncopyable and is_lightweight_proxy customization points.)
1. Change namespace foreach --> namespace foreach_ foreach:: --> foreach_:: in boost/foreach.hpp and boost/foreach_fwd.hpp.
2. Change foreach:: --> foreach_:: in boost/multi_index/hashed_index.hpp boost/multi_index/ordered_index.hpp boost/multi_index/random_access_index.hpp boost/multi_index/sequenced_index.hpp (and, if you want, libs/foreach/test/noncopyable.cpp).
Thanks for that suggestion, will try for sure. For now tho I just removed new code that was added to multi-index in 1.48 (to support foreach) and all seems to work OK. Cheers, Simon

Szymon Gatner wrote:
If you can control the ordering, you can avoid the problem. But this solution is error prone.
Yup, can't really do this now.
Making your own header file and defining `foreach` macro in the header might be a better solution: // my_foreach.h #include <boost/foreach.hpp> #include <boost/multi_index_container.hpp> #include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/random_access_index.hpp> #include <boost/multi_index/sequenced_index.hpp> #define foreach BOOST_FOREACH Then, whenever you use `foreach`, include this header file. By doing so, you don't have to worry about the ordering of header files and the macro definition. Regards, Michel

Michel Morin wrote:
// my_foreach.h #include <boost/foreach.hpp>
#include <boost/multi_index_container.hpp> #include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/random_access_index.hpp> #include <boost/multi_index/sequenced_index.hpp>
Oops, this should be // my_foreach.h #include <boost/foreach.hpp> #include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/random_access_index.hpp> #include <boost/multi_index/sequenced_index.hpp> #define foreach BOOST_FOREACH (boost/multi_index_container.hpp is not needed.) Regards, Michel

Szymon Gatner <szymon.gatner <at> gmail.com> writes:
Hi,
I realize this is not really a multi-index bug but after I updated from 1.47 to 1.48 my code no longer compiles due to this code:
[...]
btw, 1.47 version has no explicit section marked as
/* Boost.Foreach compatibility */
yet I used BOOST_FOREACH macro on many indices all over the place.
This bit was included in Boost 1.48 for reasons explained at https://svn.boost.org/trac/boost/ticket/5741 I think it is extremely unfortunate that Boost.Foreach advises people to #define foreach when this is an internal name of the library. Sorry about this, I don't think I can do anything to solve it from Boost.MultiIndex. Joaquín M López Muñoz Telefónica Digital
participants (4)
-
Joaquin M Lopez Munoz
-
Michel Morin
-
Rob Desbois
-
Szymon Gatner