http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59721
Bug ID: 59721 Summary: [4.8 Regression] std::bind nested more than one level results in infinite template substitution Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: rafal at rawicki dot org Consider following code: #include <functional> #include <iostream> struct A { struct B { struct C { C(): m(5){} int m; } c; } b; }; int main() { A::B b; auto extractor = std::bind(&A::B::C::m, std::bind(&A::B::c, std::placeholders::_1)); std::cout << extractor(b) << std::endl; A a; auto extractor2 = std::bind(&A::B::C::m, std::bind(&A::B::c, std::bind(&A::b, std::placeholders::_1))); std::cout << extractor2(a) << std::endl; return 0; } Under g++-4.7 this code compiles correctly: $ g++-4.7 -Wall -Wextra -std=c++11 bind.cpp -o bind && ./bind 5 5 while under g++-4.8 it generates infinite template recursion: $ g++-4.8 -Wall -Wextra -std=c++11 bind.cpp -o bind 2>&1 | head In file included from bind.cpp:1:0: /usr/include/c++/4.8/functional:1138:35: error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) substituting ‘template<class _Tp> typename std::add_rvalue_reference< <template-parameter-1-1> >::type std::declval() [with _Tp = A&]’ -> decltype(__arg(declval<_Args>()...)) ^ /usr/include/c++/4.8/functional:1391:40: recursively required by substitution of ‘template<class _CVArg, class ... _Args> decltype (__arg((declval<_Args>)()...)) std::_Mu<_Arg, true, false>::operator()(_CVArg&, std::tuple<_Args2 ...>&) const volatile [with _CVArg = _CVArg; _Args = {_Args ...}; _Arg = std::_Bind<std::_Mem_fn<A::B A::*>(std::_Placeholder<1>)>] [with _CVArg = const volatile std::_Bind<std::_Mem_fn<A::B A::*>(std::_Placeholder<1>)>; _Args = {A&}]’ /usr/include/c++/4.8/functional:1391:40: required by substitution of ‘template<class _CVArg, class ... _Args, long unsigned int ..._Indexes> decltype (__arg((declval<_Args>)()...)) std::_Mu<_Arg, true, false>::__call(_CVArg&, std::tuple<_Args2 ...>&, const std::_Index_tuple<_Indexes ...>&) const volatile [with _CVArg = _CVArg; _Args = {_Args ...}; long unsigned int ..._Indexes = {_Indexes ...}; _Arg = std::_Bind<std::_Mem_fn<A::B::C A::B::*>(std::_Bind<std::_Mem_fn<A::B A::*>(std::_Placeholder<1>)>)>] [with _CVArg = std::_Bind<std::_Mem_fn<A::B::C A::B::*>(std::_Bind<std::_Mem_fn<A::B A::*>(std::_Placeholder<1>)>)>; _Args = {A&}; long unsigned int ..._Indexes = {0ul}]’ /usr/include/c++/4.8/functional:1143:50: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) substituting ‘template<class _Tp> typename std::add_rvalue_reference< <template-parameter-1-1> >::type std::declval() [with _Tp = A&]’ /usr/include/c++/4.8/functional:1391:40: recursively required by substitution of ‘template<class _CVArg, class ... _Args> decltype (__arg((declval<_Args>)()...)) std::_Mu<_Arg, true, false>::operator()(_CVArg&, std::tuple<_Args2 ...>&) const volatile [with _CVArg = _CVArg; _Args = {_Args ...}; _Arg = std::_Bind<std::_Mem_fn<A::B A::*>(std::_Placeholder<1>)>] [with _CVArg = const volatile std::_Bind<std::_Mem_fn<A::B A::*>(std::_Placeholder<1>)>; _Args = {A&}]’ /usr/include/c++/4.8/functional:1391:40: required by substitution of ‘template<class _CVArg, class ... _Args, long unsigned int ..._Indexes> decltype (__arg((declval<_Args>)()...)) std::_Mu<_Arg, true, false>::__call(_CVArg&, std::tuple<_Args2 ...>&, const std::_Index_tuple<_Indexes ...>&) const volatile [with _CVArg = _CVArg; _Args = {_Args ...}; long unsigned int ..._Indexes = {_Indexes ...}; _Arg = std::_Bind<std::_Mem_fn<A::B::C A::B::*>(std::_Bind<std::_Mem_fn<A::B A::*>(std::_Placeholder<1>)>)>] [with _CVArg = std::_Bind<std::_Mem_fn<A::B::C A::B::*>(std::_Bind<std::_Mem_fn<A::B A::*>(std::_Placeholder<1>)>)>; _Args = {A&}; long unsigned int ..._Indexes = {0ul}]’ /usr/include/c++/4.8/functional:1143:50: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) substituting ‘template<class _Tp> typename std::add_rvalue_reference< <template-parameter-1-1> >::type std::declval() [with _Tp = A&]’ My g++ is: $ g++-4.8 --version g++-4.8 (Ubuntu/Linaro 4.8.2-8) 4.8.2 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.