Opened 9 years ago
Closed 9 years ago
#8668 closed Bugs (wontfix)
BOOST_FOREACH breaks on clang 3.2 but not on gcc 4.7.2
| Reported by: | Owned by: | Eric Niebler | |
|---|---|---|---|
| Milestone: | To Be Determined | Component: | foreach |
| Version: | Boost 1.52.0 | Severity: | Problem |
| Keywords: | Cc: |
Description
Consider this snippet:
#include <vector>
#include <boost/foreach.hpp>
class A : public std::vector<int>
{
public:
template <class T>
operator const T &() const;
};
void foo(){
A colA;
int b = 1;
BOOST_FOREACH(b, colA)
{
;
}
}
clang 3.2 throws this error:
error: conditional expression is ambiguous; 'rvalue_probe<A>' can be converted to 'A' and vice versa BOOST_FOREACH(b, colA) expanded from macro 'BOOST_FOREACH' f (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) expanded from macro 'BOOST_FOREACH_CONTAIN' BOOST_FOREACH_EVALUATE(COL) expanded from macro 'BOOST_FOREACH_EVALUATE' (true ? boost::foreach_detail_::make_probe((COL), BOOST_FOREACH_ID(_foreach_is_rvalue)) : (COL))
gcc in version 4.7.2 compiles this snippet with no error. Is this a bug of gcc, clang or boost?
Change History (2)
comment:1 by , 9 years ago
| Component: | None → foreach |
|---|---|
| Owner: | set to |
comment:2 by , 9 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
Note:
See TracTickets
for help on using tickets.

It's not really a bug in gcc, clang, or boost. It's because in C++03, there's no perfect way to tell rvalues from lvalues.
BOOST_FOREACHjumps through hoops of fire to figure it out, and it gets it right %100 of the time, +/- some epsilon. Congrats, you've found the epsilon. ;-)If your container has an unconstrained conversion operator template, like
Adoes above, it's not going to work. I think clang is right to reject it. The workaround is to compile with-std=gnu++11or use C++11's range-basedforloop. I'm afraid there's no way I know to make this work in C++03.I encourage you to migrate to C++11.
BOOST_FOREACHis legacy.