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: rob.desbois@… 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)

invoke-boost-failure.cpp (388 bytes ) - added by rob.desbois@… 6 years ago.
Minimal failing test case

Download all attachments as: .zip

Change History (2)

by rob.desbois@…, 6 years ago

Attachment: invoke-boost-failure.cpp added

Minimal failing test case

comment:1 by Michel Morin, 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.

Note: See TracTickets for help on using tickets.