<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/105764>105764</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libcxx] std::function doesn't with non-movable but copyable type
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc++
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
cw118876
</td>
</tr>
</table>
<pre>
Here is a buggy test program with a std::function :
code snipper
`#include <iostream>
#include <utility>
#include <functional>
#include <type_traits>
class Test {
int a = 1;
int b = 1;
public:
Test() = default;
Test(const Test&) = default;
Test& operator=(const Test&) = default;
Test(Test&&) = delete;
Test& operator=(Test&&) =delete;
int operator()(int first, int second) {
return a + b + first + second;
}
};
int main(int argc, const char* argv[]) {
// std::cout << HasMember<Test>::value << "\n";
Test t{};
std::function<int(int, int) > f(t);
std::cout << f(12, 123) << "\n";
return 0;
}`
Compiler information: clang 18.1.0 x64
compile flags: -stdlib=libc++
compile error information:
`opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/compressed_pair.h:60:9: error: call to deleted constructor of 'Test'
60 | : __value_(std::forward<_Args>(std::get<_Indices>(__args))...) {}
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__memory/compressed_pair.h:129:9: note: in instantiation of function template specialization 'std::__compressed_pair_elem<Test, 0>::__compressed_pair_elem<Test &&, 0UL>' requested here
129 | : _Base1(__pc, std::move(__first_args), typename __make_tuple_indices<sizeof...(_Args1)>::type()),
| ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__functional/function.h:183:11: note: in instantiation of function template specialization 'std::__compressed_pair<Test, std::allocator<Test>>::__compressed_pair<Test &&, std::allocator<Test> &&>' requested here
183 | : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
| ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__functional/function.h:308:11: note: in instantiation of member function 'std::__function::__alloc_func<Test, std::allocator<Test>, int (int, int)>::__alloc_func' requested here
308 | : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
| ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__functional/function.h:424:44: note: in instantiation of member function 'std::__function::__func<Test, std::allocator<Test>, int (int, int)>::__func' requested here
424 | ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af));
| ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__functional/function.h:439:11: note: in instantiation of function template specialization 'std::__function::__value_func<int (int, int)>::__value_func<Test, std::allocator<Test>>' requested here
439 | : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {}
| ^
/opt/compiler-explorer/clang-17.0.1/bin/../include/c++/v1/__functional/function.h:1111:50: note: in instantiation of function template specialization 'std::__function::__value_func<int (int, int)>::__value_func<Test, void>' requested here
1111 | function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {}
| ^
<source>:29:35: note: in instantiation of function template specialization 'std::function<int (int, int)>::function<Test, void>' requested here
29 | std::function<int(int, int) > f(t);
| ^
<source>:16:4: note: 'Test' has been explicitly marked deleted here
16 | Test(Test&&) = delete;
`
**But this test program works with GCC**.
According to cppreference [std::function:](https://en.cppreference.com/w/cpp/utility/functional/function/function) :
`template< class F >
function( F&& f );
`
"Initializes the target with [std::forward](http://en.cppreference.com/w/cpp/utility/forward)<F>(f). The target is of type [std::decay](http://en.cppreference.com/w/cpp/types/decay)<F>::type."
Maybe, problem occurs, due to forcely moving the object instead of forwarding the object in follow [code.](https://github.com/llvm/llvm-project/blob/llvmorg-18.1.0/libcxx/include/__functional/function.h)
` if (__function::__not_null(__f)) {
_FunAlloc __af(__a);
if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value &&
is_nothrow_copy_constructible<_FunAlloc>::value) {
__f_ = ::new ((void*)&__buf_) _Fun**(std::move(__f)**, _Alloc(__af));
} else {
typedef __allocator_destructor<_FunAlloc> _Dp;
unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a));
__f_ = __hold.release();
}
}
}`
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWc1y47gRfhr40mUVCUoiddBBpqzsVmUvySRXFki2JGRAgguA9mgPefYUAP5Klsezmdldl4sSgQb65-tudENMa36qEbdk9URW-wfWmrNU2-I1DJMkXj_ksrxsf0KFwDUwyNvT6QIGtYFGyZNiFbxycwYG2pQk2pFod2zrwnBZA9j3YE-CXSFLBF3zpkHlR8g6IDTidSHaEoFEKZfaKGQViZ47itl0a7jg5nJntmfJxEgwfc6IzaXBzCjGjb6iLgTTGj5Z5Uj85McAgNcGGJBoDyGJ5sP51XDT5oIXg94AbjdCE0I3jrTEI2uFme7TURSy1qZ7Wd8l7-ZBNqiYkYpE-4-uvWY4kE9WCDT4NWY3666XedMMi5zyhCZ28MiVXZw6Co2FrEu3ycTaoNC0qrYWp0_WwPTJL3PfujUTXiTed987NeP9lcr-aTlWjNedJEydCiuIN11xZorQnR198YFwIxahB0IPo5sXsjXWnUiUwk9M_4JVjopEqTNP9OyJXphosacilJJVWtuPifze34zldSP5bVDZSKmN16Gzo0fhGY6EJvZltvmb4lrKkNrlIY388vcEvIEmGMWM9zaS3fdUVg0XqIDXR6kq5sXdQSFYfYIwWYSLAL6sl31KcNRwFOykLdmjNqXgOYn2gucFoU_2fxqc3QJUSl7zGHKKbAyhh45UPeKXRkiFyo5ZKR7DeBEsQkIPuXWEw2JB6KFLDZam40oPL5YmyyqspLp0OyrUGsusYVwtziTarQMS7TZWdCeSU5UJAUZ2gVR651JtYaQCeQRCYx888WDSdQAkTsH_2S2yzPlMRmgygi_VK1MlidJsp04ua01mT2jszM91yQvsJrOMWUIbd5uF1dI78xAqnl2cAlk9w3-_7a_PqYc_0tih9Wtv7VraZLMDXgOvtWG14c4PrIWHs8dg1QhmEHSDBWeC_-ZpCI0Hw2XZFacMBVZ9CNPU-vnzB0ihz4YpBP_6uwMgBoW_tqitE5xRYW_20AExw_uJaQwdZI1LSIN4lXxBN-6y3whoCvYEq1mFkGUV-4yZaRuBGe8dINX8N5RHh3viPCZ0aaHTxa7uk7Ld7g2X-FEQT85peuhfPL5JZJ_hjwV4gu1AxISQhT_dxtx9D_ZbxN_bpyd71yOSaOIRfQ442vhvOBb4yjVmQx6xHLN___PTfpYYMqa9D1i8x9nRga6x_tNgjoLkQzBX7jQd0Z6jOh6G_t2Z3o1-FOCuArk-RyfAT_a8i10UJPewuw_DDMBhjnmI7mfpPx6rJV3a5_L7YvV9UXofnyVdevM56hpfweW95EXyktCdM_k6y_LWQraB7NDWX4NuZ8X0iPVRNS2V_ky4os2PyKDX-PnqpEPxK-jMaD-aeO-jGW3eiLYJjxl0k5rp0PRFUQ_jlPUw_deLwDB0cK6CvzqmLqDewc4q4sw4aWOyfzRdefLp0qD2VerAaCCkSXZowEP3sQT7dQijVMtWFei5ucoyWn1XG8_btfv2nNB91JYAkxry_-4P3zdNuLaJZWqZsYWBM9OQI9ZgA4AX3IgLVEx9xnLof2Zih-te7I9eQAytpUvWu6fWgDlzfXX9JNVn7S-h_pamnnIxbRx3RSFVyeuT7cyKplF4RIV1gUBWT28YcOe6_-RsTGMbU9_3Y72YLl0UsiL08GrjuWkIPfT3U2MEz8J59nUD05a1dyfbgPsLqAMM91KTMICDtxXYPtKCCDdGoj_X3DiPRA3mjGCYOqHxxpkp2yXHQdHfo2e3h5UlPfgUagNwAZ9Gzlzb0LEdx4x_iQW7_A7udiNN6MGvHzkPfc2CUDq7QPmFXXK0gdAomQusQBZFq7QdKVu0HnGUqkDruvLF-cgZQeb_wcK4FICsdMHvlb0hgKMUQr5a5QpZ4uIt1zlxc27zThchXvqPx0ZJu409KITMu1GpTo_-rsQO8Lz48mV2fNw_L-hmcAjg1kmS20xfS5PVrRA36XKSEGwZ5Moc8EVOX50OacNv7ptMl5_berhE2sM4PhRWneNybfmflXzNCtlcxq6G5wLHk3h6ceazQ8f2q8s7ueebvKEhuEPEZZxvKg19Hkre6NAdvZ_-WJG4BxQabwWzTlziEboGxNYoWYn9JdKVlpDtm3Hntua_tpg1xpF1JVHqaZ4hy85SlJ1Qi25zK33Yl7b7ZhA5hfBa7vuG8jsvTmjGIqorpe9Zam6ja1YDON3OCgUy3d9Z3FhyclE5vkwvJqfPh3IblZtowx5wG8Z0GcXrJA4fztsgWLMoDlbrKArWSVCGySYujptVvI6QYhw-8C0N6DJIaBSE0TIKF0m4DBlbrctNQldRUZBlgBXjYmHDeCHV6YFr3eI2DFbxevkgWI5Cu59ZKJ1ccVJKVvsHtXUpIW9PmiwDwbXR4z6GG-F-oOnywWr_xq8tpURdExp36b6W9WMlX1guEPLWgA0Z92I97KFVYvvNWcqpY9Nvp9HLlv4vAAD__yUHy3E">