http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57684

            Bug ID: 57684
           Summary: [c++11] Lambda is not convertible to std::function
           Product: gcc
           Version: 4.8.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bluescarni at gmail dot com

Created attachment 30344
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30344&action=edit
Code snippet demonstrating the problem.

A specific setup with CRTP pattern and a static unordered_map member in the
base class is preventing conversion from a lambda expression to an
std::function. The problem is reproduced in the attached code snippet. The
error produced by GCC 4.8.1 is:

----
main.cpp: In function ‘int main()’:
main.cpp:20:3: error: no matching function for call to
‘std::function<derived(const derived&)>::function(main()::__lambda0)’
  });
   ^
main.cpp:20:3: note: candidates are:
In file included from main.cpp:1:0:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2255:2: note:
template<class _Functor, class> std::function<_Res(_ArgTypes
...)>::function(_Functor)
  function(_Functor);
  ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2255:2: note: 
 template argument deduction/substitution failed:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2230:7: note:
std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes
...)>&&) [with _Res = derived; _ArgTypes = {const derived&}]
       function(function&& __x) : _Function_base()
       ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2230:7: note: 
 no known conversion for argument 1 from ‘main()::__lambda0’ to
‘std::function<derived(const derived&)>&&’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2433:5: note:
std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes
...)>&) [with _Res = derived; _ArgTypes = {const derived&}]
     function<_Res(_ArgTypes...)>::
     ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2433:5: note: 
 no known conversion for argument 1 from ‘main()::__lambda0’ to ‘const
std::function<derived(const derived&)>&’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2210:7: note:
std::function<_Res(_ArgTypes ...)>::function(std::nullptr_t) [with _Res =
derived; _ArgTypes = {const derived&}; std::nullptr_t = std::nullptr_t]
       function(nullptr_t) noexcept
       ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2210:7: note: 
 no known conversion for argument 1 from ‘main()::__lambda0’ to
‘std::nullptr_t’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2203:7: note:
std::function<_Res(_ArgTypes ...)>::function() [with _Res = derived; _ArgTypes
= {const derived&}]
       function() noexcept
       ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/functional:2203:7: note: 
 candidate expects 0 arguments, 1 provided
----

(Sorry for not being able to reduce the test case further, but I was able to
reproduce the problem only by pulling in std::unordered_map. GCC 4.7.3 and
Clang++ 3.3 both compile the snippet without errors.)

The problem disappears if one replaces the static member definition with one of
the commented lines or even if one replaces the existing main() body with this:

----
    std::function<void (const derived &)> foo([](const derived &d) {
        return d;
    });
----

I.e., by changing the std::function to return void instead of derived.

Reply via email to