http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58569
Bug ID: 58569 Summary: Compilation error when copying class which contains multiple std::function Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: pierre.krieger1708 at gmail dot com Created attachment 30924 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30924&action=edit The preprocessed file This simple code snippet fails to compile: #include <functional> struct foo { std::function<foo (int)> x; std::function<foo ()> y; }; int main(int argc, char const* argv[]) { foo a; return 0; } The problem happens if a class contains at least two std::function of different type which return the class itself. If you remove the "int" from "foo (int)", it works. If you remove either member "x" or "y", it works. With g++4.8.1 and flag -std=c++11: In file included from test.cpp:1:0: /usr/include/c++/4.8/functional: In instantiation of ‘struct std::function<foo()>::_CheckResult<foo, foo>’: /usr/include/c++/4.8/functional:2192:63: required by substitution of ‘template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond:: value, _Tp>::type [with _Cond = std::function<foo()>::_CheckResult<foo, foo>; _Tp = void; _Res = foo; _ArgTypes = {}]’ /usr/include/c++/4.8/functional:2254:9: required by substitution of ‘template<class _From1, class _To1> static decltype ((__test_aux<_To1>(declval<_From1>()), std::__sfinae_types::__one())) std::__is_convertible_helper<_From, _To, false>::__test(int) [with _From1 = _From1; _To1 = _To1; _From = foo; _To = foo] [with _From1 = foo; _To1 = foo]’ /usr/include/c++/4.8/type_traits:1312:50: required from ‘constexpr const bool std::__is_convertible_helper<foo, foo, false>::value’ /usr/include/c++/4.8/type_traits:1317:12: required from ‘struct std::is_convertible<foo, foo>’ /usr/include/c++/4.8/functional:2181:9: required from ‘struct std::function<foo(int)>::_CheckResult<foo, foo>’ /usr/include/c++/4.8/functional:2192:63: required by substitution of ‘template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond:: value, _Tp>::type [with _Cond = std::function<foo(int)>::_CheckResult<foo, foo>; _Tp = void; _Res = foo; _ArgTypes = {int}]’ /usr/include/c++/4.8/functional:2254:9: required from here /usr/include/c++/4.8/functional:2181:9: error: invalid use of incomplete type ‘struct std::is_convertible<foo, foo>’ struct _CheckResult ^ In file included from /usr/include/c++/4.8/bits/move.h:57:0, from /usr/include/c++/4.8/bits/stl_pair.h:59, from /usr/include/c++/4.8/utility:70, from /usr/include/c++/4.8/tuple:38, from /usr/include/c++/4.8/functional:55, from test.cpp:1: /usr/include/c++/4.8/type_traits:1317:12: error: declaration of ‘struct std::is_convertible<foo, foo>’ struct is_convertible ^ /usr/include/c++/4.8/type_traits: In substitution of ‘template<class _From1, class _To1> static decltype ((__test_aux<_To1>(declval<_From1>()), std::__sfinae_types::__one())) std::__is_convertible_helper<_From, _To, false>::__test(int) [with _From1 = _From1; _To1 = _To1; _From = foo; _To = foo] [with _From1 = foo; _To1 = foo]’: /usr/include/c++/4.8/type_traits:1312:50: required from ‘constexpr const bool std::__is_convertible_helper<foo, foo, false>::value’ /usr/include/c++/4.8/type_traits:1317:12: required from ‘struct std::is_convertible<foo, foo>’ /usr/include/c++/4.8/functional:2181:9: required from ‘struct std::function<foo(int)>::_CheckResult<foo, foo>’ /usr/include/c++/4.8/functional:2192:63: required by substitution of ‘template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond:: value, _Tp>::type [with _Cond = std::function<foo(int)>::_CheckResult<foo, foo>; _Tp = void; _Res = foo; _ArgTypes = {int}]’ /usr/include/c++/4.8/functional:2254:9: required from here /usr/include/c++/4.8/type_traits:1302:21: error: initializing argument 1 of ‘static void std::__is_convertible_helper<_From, _To, false>::__test_aux(_To1) [with _To1 = foo; _From = foo; _To = foo]’ static void __test_aux(_To1);