Opened 13 years ago
Closed 13 years ago
#3021 closed Bugs (fixed)
proto::extends compilation error with function type on gcc-3.4.5
| Reported by: | Owned by: | Eric Niebler | |
|---|---|---|---|
| Milestone: | Boost 1.40.0 | Component: | proto |
| Version: | Boost Development Trunk | Severity: | Problem |
| Keywords: | proto extends function gcc DR214 | Cc: |
Description
The following test case has been simplified from Spirit's actions.cpp test case. This does not compile with gcc-3.4.5 or 3.4.6:
#include <boost/proto/proto.hpp>
using namespace boost::proto;
void func() {}
struct my_tag {};
struct my_terminal :
extends< terminal<my_tag>::type, my_terminal >
{};
my_terminal const foo = my_terminal();
int main()
{
foo[&func]; // OK
foo[func]; // fails with gcc-3.4.5 and 3.4.6
return 0;
}
with this error:
boost/proto/extends.hpp: In member function '...': test.cpp:15: instantiated from here boost/proto/extends.hpp:505: error: call of overloaded `as_child(void (&)())' is ambiguous boost/proto/traits.hpp:2050: note: candidates are: typename result_of::as_child<T, Domain, void>::type as_child(T&, typename disable_if<is_const<T>, detail::undefined>::type*) [with Domain = default_domain, T = void ()()] boost/proto/traits.hpp:2059: note: typename result_of::as_child<const T, Domain, void>::type as_child(const T&) [with Domain = default_domain, T = void ()()]
(but it works fine with gcc-4.1.2 and later).
I think it is because these versions of gcc do not implement DR-214 resolution (Partial ordering of function templates, see gcc bug #19203), so:
- since the disable_if on as_child does not disable the non-const overload (since the function type is not const),
- gcc reports the 2 overloads as ambiguous instead of choosing the const one.
A solution would probably be to also disable the non-const as_child overload if the argument type is a function?
Thanks,
François
Note:
See TracTickets
for help on using tickets.

(In [53158]) workaround for gcc-3.4 bug, fixes #3021