This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/81211] New: Unhelpful error messages using template instance with non-copyable type argument
- From: "srk31 at srcf dot ucam.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 26 Jun 2017 14:52:58 +0000
- Subject: [Bug c++/81211] New: Unhelpful error messages using template instance with non-copyable type argument
- Auto-submitted: auto-generated
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.