[foreach][assign] Does foreach work with assign::list_of?

This simple example doesn't compile with GCC 4.4 + Boost 1.46.1: #include <boost/assign/list_of.hpp> #include <boost/foreach.hpp> #include <iostream> int main() { BOOST_FOREACH( int i, boost::assign::list_of(3)(1)(4)(1)(5) ) std::cout << i << ' '; } error: operands to ?: have different types 'const boost::foreach_detail_::rvalue_probe<boost::assign_detail::generic_list<int> >' and 'boost::assign_detail::generic_list<int>' I believe both Foreach and Assign library are to ease sequence creation/iteration on the fly, so they should work together smoothly. Thanks, Maxim

MaximYanchenko wrote:
This simple example doesn't compile with GCC 4.4 + Boost 1.46.1:
#include <boost/assign/list_of.hpp> #include <boost/foreach.hpp> #include <iostream>
int main() { BOOST_FOREACH( int i, boost::assign::list_of(3)(1)(4)(1)(5) ) std::cout << i << ' '; }
error: operands to ?: have different types 'const boost::foreach_detail_::rvalue_probe<boost::assign_detail::generic_list<int> >' and 'boost::assign_detail::generic_list<int>'
I believe both Foreach and Assign library are to ease sequence creation/iteration on the fly, so they should work together smoothly.
The problem is that `generic_list<T>` (a return value of `assign::list_of()`) has very generic conversion operator: template<class Container> operator Container() const; This generic conversion operator leads to the compiler error; Containers used with `BOOST_FOREACH` should not be convertible to `rvalue_probe`. In the above case, `generic_list<T>` is convertible to `rvalue_probe< generic_list<T> >` and the compiler error happens. If SFINAE could be used with conversion operators, we could selectively disable problematic conversions. Unfortunately, we cannot apply SFINAE to conversion operators in C++03. Regards, Michel

On 13/06/2011 09:56, Michel MORIN wrote:
The problem is that `generic_list<T>` (a return value of `assign::list_of()`) has very generic conversion operator: template<class Container> operator Container() const;
This generic conversion operator leads to the compiler error; Containers used with `BOOST_FOREACH` should not be convertible to `rvalue_probe`. In the above case, `generic_list<T>` is convertible to `rvalue_probe< generic_list<T> >` and the compiler error happens.
If SFINAE could be used with conversion operators, we could selectively disable problematic conversions. Unfortunately, we cannot apply SFINAE to conversion operators in C++03.
Or BOOST_FOREACH could be changed to work differently.

On 6/13/2011 7:11 PM, Mathias Gaunard wrote:
On 13/06/2011 09:56, Michel MORIN wrote:
The problem is that `generic_list<T>` (a return value of `assign::list_of()`) has very generic conversion operator: template<class Container> operator Container() const;
This generic conversion operator leads to the compiler error; Containers used with `BOOST_FOREACH` should not be convertible to `rvalue_probe`. In the above case, `generic_list<T>` is convertible to `rvalue_probe< generic_list<T> >` and the compiler error happens.
If SFINAE could be used with conversion operators, we could selectively disable problematic conversions. Unfortunately, we cannot apply SFINAE to conversion operators in C++03.
Or BOOST_FOREACH could be changed to work differently.
Sure. Just tell me how else to detect const rvalues in standard C++98. Eagerly-awaiting-your-reply-ly, -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 14/06/2011 06:55, Eric Niebler wrote:
Or BOOST_FOREACH could be changed to work differently.
Sure. Just tell me how else to detect const rvalues in standard C++98.
Implementation of BOOST_FOREACH seems, large, quirky, and to contain quite a few limitations. With Boost.Typeof or decltype, I can write a robust implementation in a couple of lines that is also likely to yield better code. With compilers evolving, we could make the implementation of BOOST_FOREACH evolve too. It would also be nice to strip extra parentheses on compilers that are capable of it, add BOOST_FOREACH_AUTO variants, and be able to leverage native foreach-support where available. I've already had a variant of BOOST_FOREACH that does that in my code for years. Legacy compatibility is nice, but a tool that allows to make the best of ranges on today's compilers is very important too.
participants (4)
-
Eric Niebler
-
Mathias Gaunard
-
MaximYanchenko
-
Michel MORIN