https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81211
Bug ID: 81211 Summary: Unhelpful error messages using template instance with non-copyable type argument Product: gcc Version: 6.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: srk31 at srcf dot ucam.org Target Milestone: --- Created attachment 41631 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41631&action=edit Small test case The following code (also attached) fails to compile, and experiments show that the fix is to make T copy-constructible or move-constructible. The bug is that the error messages are worse than useless, because they are about constructing a std::function rather than a T. (It may also be a bug in libstdc++ that std::function should require this of its argument type, although that's not completely bonkers.) #include <functional> struct T { T() {} // uncomment one of the below to make the code compile //T(const T&) {} //T(T&& t) {} T& operator=(const T& arg) { return *this; } T& operator=(T&& arg) { return *this; } }; int main(int argc, char **argv) { std::function<bool(T)> f([](T x) -> bool { return false; }); return 0; } gcc 4.9 (Debian 4.9.2-10) says: test.cc: In function ‘int main(int, char**)’: test.cc:15:3: error: no matching function for call to ‘std::function<bool(T)>::function(main(int, char**)::<lambda(T)>)’ }); ^ test.cc:15:3: note: candidates are: In file included from test.cc:1:0: /usr/include/c++/4.9/functional:2226:2: note: template<class _Functor, class> std::function<_Res(_ArgTypes ...)>::function(_Functor) function(_Functor); ^ /usr/include/c++/4.9/functional:2226:2: note: template argument deduction/substitution failed: /usr/include/c++/4.9/functional:2201:7: note: std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = bool; _ArgTypes = {T}] function(function&& __x) : _Function_base() ^ /usr/include/c++/4.9/functional:2201:7: note: no known conversion for argument 1 from ‘main(int, char**)::<lambda(T)>’ to ‘std::function<bool(T)>&&’ /usr/include/c++/4.9/functional:2404:5: note: std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes ...)>&) [with _Res = bool; _ArgTypes = {T}] function<_Res(_ArgTypes...)>:: ^ /usr/include/c++/4.9/functional:2404:5: note: no known conversion for argument 1 from ‘main(int, char**)::<lambda(T)>’ to ‘const std::function<bool(T)>&’ /usr/include/c++/4.9/functional:2181:7: note: std::function<_Res(_ArgTypes ...)>::function(std::nullptr_t) [with _Res = bool; _ArgTypes = {T}; std::nullptr_t = std::nullptr_t] function(nullptr_t) noexcept ^ /usr/include/c++/4.9/functional:2181:7: note: no known conversion for argument 1 from ‘main(int, char**)::<lambda(T)>’ to ‘std::nullptr_t’ /usr/include/c++/4.9/functional:2174:7: note: std::function<_Res(_ArgTypes ...)>::function() [with _Res = bool; _ArgTypes = {T}] function() noexcept ^ /usr/include/c++/4.9/functional:2174:7: note: candidate expects 0 arguments, 1 provided Meanwhile, g++ 6 (Debian 6.3.0-18) says basically the same thing. Naively at least, I'd expect the error trace to reveal something about trying to copy a T, presumably in some non-viable constructor of std::function.