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(); } ~~^~~