Opened 6 years ago
Last modified 6 years ago
#12249 new Bugs
Wrong operator|() overload being found on multiple platforms & causing compilation failure
| Reported by: | Owned by: | Neil Groves | |
|---|---|---|---|
| Milestone: | To Be Determined | Component: | range |
| Version: | Boost 1.61.0 | Severity: | Problem |
| Keywords: | Cc: |
Description
When using the pipe syntax (operator| overloads) for range adaptors I'm finding that the overloads taking replace_holder are being incorrectly selected when using other adaptors over a range exposing abstract base class references.
I can reproduce this with filtered, transformed and indexed adaptors; on Clang, gcc & MSVC; and with Boost 1.57 and 1.61.
The minimal failing testcase is attached, and compiles fine when the replaced.hpp include is commented out.
The error I get with clang for the attached file is:
In file included from invoke-boost-failure.cpp:1:
In file included from /usr/include/boost/range/adaptor/indexed.hpp:23:
/usr/include/boost/range/adaptor/argument_fwd.hpp:36:15: error: field type 'Base' is an abstract class
T val1, val2;
^
/usr/include/boost/range/adaptor/replaced.hpp:93:39: note: in instantiation of template class 'boost::range_detail::holder2<Base>' requested here
class replace_holder : public holder2<T>
^
invoke-boost-failure.cpp:17:33: note: in instantiation of template class 'boost::range_detail::replace_holder<Base>' requested here
for (const auto& b : refs | boost::adaptors::indexed())
^
invoke-boost-failure.cpp:8:13: note: unimplemented pure virtual method '~Base' in 'Base'
virtual ~Base() = 0;
^
In file included from invoke-boost-failure.cpp:1:
In file included from /usr/include/boost/range/adaptor/indexed.hpp:23:
/usr/include/boost/range/adaptor/argument_fwd.hpp:36:21: error: field type 'Base' is an abstract class
T val1, val2;
^
2 errors generated.
I can work around this by using the function call syntax for adaptors, but I can't suggest a fix as I don't understand why that overload is being selected at all.
Attachments (1)
Change History (2)
by , 6 years ago
| Attachment: | invoke-boost-failure.cpp added |
|---|
comment:1 by , 6 years ago
During the overload resolution of operator |, the operator for
replaced_range is instantiated if replaced.hpp is included
and the associated namespaces contain boost::range_detail.
This instantiation results in a hard error, if the range's value type is
an abstract type.
This problem can be fixed by adding SFINAE-based constraints to operator |
for replaced_range so that the range's value type is not an abstract type.

Minimal failing test case