https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80767
Bug ID: 80767
Summary: Eager instantiation of member template when not
required
Product: gcc
Version: 7.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: barry.revzin at gmail dot com
Target Milestone: ---
Here's a simplifed example of overloading taking from StackOverflow question
http://stackoverflow.com/q/43982799/2069064:
template <typename... Fs>
struct overloader : Fs...
{
overloader(Fs... fs)
: Fs(fs)...
{ }
using Fs::operator()...;
};
struct a { void foo() { } };
struct b { void bar() { } };
struct c { void bar() { } };
struct CallFoo {
auto operator()(a x) const { x.foo(); }
};
int main() {
overloader{
#ifdef BUG
[](a x) { x.foo(); },
#else
CallFoo{},
#endif
[](auto x) { x.bar(); }
}(a{});
}
If BUG is not defined, this compiles fine. But if BUG is defined (which just
swaps a lambda for an equivalent funject), the generic lambda's call operator
is instantiated (even though the non-generic lambda should be preferred) and
the program fails to compile with:
foo.cxx: In instantiation of ‘main()::<lambda(auto:1)> [with auto:1 = a]’:
foo.cxx:26:18: required by substitution of ‘template<class auto:1> constexpr
main()::<lambda(auto:1)>::operator decltype (((const
main()::<lambda(auto:1)>*)((const main()::<lambda(auto:1)>*
const)0))->operator()(static_cast<auto:1&&>(<anonymous>))) (*)(auto:1)() const
[with auto:1 = a]’
foo.cxx:27:10: required from here
foo.cxx:26:24: error: ‘struct a’ has no member named ‘bar’
[](auto x) { x.bar(); }
~~^~~