【问题标题】:Different behavior between libstdc++ and libc++ when constructing std::function with lambda使用 lambda 构造 std::function 时 libstdc++ 和 libc++ 之间的不同行为
【发布时间】:2014-06-10 08:09:54
【问题描述】:

这个问题来自this question

以下代码compiles fine 使用带有 libstdc++ 的 clang 3.4:

#include <functional>

int main() {
    std::function<void()> f = []() {};
}

但是 fails miserably 使用 clang 3.4 和 libc++:

In file included from main.cpp:1:
In file included from /usr/include/c++/v1/functional:465:
In file included from /usr/include/c++/v1/memory:599:
/usr/include/c++/v1/tuple:320:11: error: rvalue reference to type '<lambda at main.cpp:4:31>' cannot bind to lvalue of type '<lambda at main.cpp:4:31>'
        : value(__t.get())
          ^     ~~~~~~~~~
/usr/include/c++/v1/tuple:444:8: note: in instantiation of member function 'std::__1::__tuple_leaf<0, <lambda at main.cpp:4:31> &&, false>::__tuple_leaf' requested here
struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
       ^
/usr/include/c++/v1/functional:1278:26: note: in instantiation of member function 'std::__1::__function::__func<<lambda at main.cpp:4:31>, std::__1::allocator<<lambda at main.cpp:4:31> >, void ()>::__func' requested here
            ::new (__f_) _FF(_VSTD::move(__f));
                         ^
main.cpp:4:31: note: in instantiation of function template specialization 'std::__1::function<void ()>::function<<lambda at main.cpp:4:31> >' requested here
    std::function<void()> f = []() {};
                              ^
In file included from main.cpp:1:
In file included from /usr/include/c++/v1/functional:465:
In file included from /usr/include/c++/v1/memory:599:
/usr/include/c++/v1/tuple:321:10: error: static_assert failed "Can not copy a tuple with rvalue reference member"
        {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");}
         ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/v1/tuple:320:11: error: rvalue reference to type 'allocator<[...]>' cannot bind to lvalue of type 'allocator<[...]>'
        : value(__t.get())
          ^     ~~~~~~~~~
/usr/include/c++/v1/tuple:444:8: note: in instantiation of member function 'std::__1::__tuple_leaf<0, std::__1::allocator<<lambda at main.cpp:4:31> > &&, false>::__tuple_leaf' requested here
struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
       ^
/usr/include/c++/v1/functional:1286:34: note: in instantiation of member function 'std::__1::__function::__func<<lambda at main.cpp:4:31>, std::__1::allocator<<lambda at main.cpp:4:31> >, void ()>::__func' requested here
            ::new (__hold.get()) _FF(_VSTD::move(__f), allocator<_Fp>(__a));
                                 ^
main.cpp:4:31: note: in instantiation of function template specialization 'std::__1::function<void ()>::function<<lambda at main.cpp:4:31> >' requested here
    std::function<void()> f = []() {};
                              ^
In file included from main.cpp:1:
In file included from /usr/include/c++/v1/functional:465:
In file included from /usr/include/c++/v1/memory:599:
/usr/include/c++/v1/tuple:321:10: error: static_assert failed "Can not copy a tuple with rvalue reference member"
        {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");}
         ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 errors generated.

哪种行为是正确的?

【问题讨论】:

    标签: c++ c++11 lambda c++14 libc++


    【解决方案1】:

    令我惊讶的是,对于哪些实施正确,哪些实施错误存在任何疑问; sn-p 当然应该编译。 libc++ 有错误行为,下面是相关错误报告的链接。


    注意Bug 17798 已在较新版本的库实现中得到修复。

    【讨论】:

    • 是的,一旦简化为[](){} 形式,正确的行为是相当明显的。感谢您提供错误报告的链接。
    猜你喜欢
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 2019-07-06
    • 2012-02-18
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    相关资源
    最近更新 更多