Derive from shared_ptr<T> - c++

I have a strange compilation problem that I can't understand.
//I know, you should never derive from the STL Library
template<class T>
class SharedClass : private shared_ptr<T>
{
public:
template<class T2>
SharedClass(T2&& t2) :
shared_ptr<T>(make_shared<T>(move(t2)))
{}
virtual ~SharedClass()
{}
};
class A
{
public:
typedef function<void(SharedClass<A>)> Callback;
A(Callback callback)
{ }
};
main.cpp
SharedClass<A> shared([](SharedClass<A>){ });
Compile Log:
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/string:41,
from /usr/include/c++/7/bits/locale_classes.h:40,
from /usr/include/c++/7/bits/ios_base.h:41,
from /usr/include/c++/7/ios:42,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from main.cpp:9:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = A; _Args = {SharedClass<A>}; _Tp = A]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_CharT>>::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = A; _Args = {SharedClass<A>}; _Tp = A; std::allocator_traits<std::allocator<_CharT>>::allocator_type = std::allocator<A>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {SharedClass<A>}; _Tp = A; _Alloc = std::allocator<A>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’ /usr/include/c++/7
/bits/shared_ptr_base.h:637:4: required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = A; _Alloc = std::allocator<A>; _Args = {SharedClass<A>}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {SharedClass<A>}; _Tp = A; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {SharedClass<A>}; _Tp = A]’
/usr/include/c++/7/bits/shared_ptr.h:690:14: [ skipping 9 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {main()::<lambda(SharedClass<A>)>}; _Tp = A; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {main()::<lambda(SharedClass<A>)>}; _Tp = A]’ /usr/include/c++/7/bits/shared_ptr.h:690:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = A; _Alloc = std::allocator<A>; _Args = {main()::<lambda(SharedClass<A>)>}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = A; _Args = {main()::<lambda(SharedClass<A>)>}]’
main.cpp:21:33: required from ‘SharedClass<T>::SharedClass(T2&&) [with T2 = main()::<lambda(SharedClass<A>)>; T = A]’
main.cpp:39:48: required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘A::A(SharedClass)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:33:5: note: candidate: A::A(A::Callback)
A(Callback callback)
^ main.cpp:33:5: note: no known conversion for argument 1 from ‘SharedClass’ to ‘A::Callback {aka std::function)>}’
main.cpp:28:7: note: candidate: constexpr A::A(const A&)
class A
^ main.cpp:28:7: note: no known conversion for argument 1 from ‘SharedClass’ to ‘const A&’
main.cpp:28:7: note: candidate: constexpr A::A(A&&)
main.cpp:28:7: note: no known conversion for argument 1 from ‘SharedClass’ to ‘A&&’
If I change the constructor of the SharedClass class like this SharedClass (T2 t2) it compiles.

As your lambda takes its parameters by value it needs to be able to create copies of those parameters, it does this by calling the move constructor. As you have defined a templated constructor with the same signature as the move constructor the compiler attempts to use it as a move constructor. Adding default copy (for completeness) and move constructors fixes the issue:
SharedClass(const SharedClass&) = default;
SharedClass(SharedClass&&) = default;
Your existing constructor doesn't work as a move constructor because there is no constructor for A which takes a SharedClass<A> parameter so make_shared<A> doesn't compile when passed a SharedClass<A> parameter.

Related

can not compile my code with template and shared_ptr

I have some code :
#include <list>
#include <iostream>
#include <string>
class A
{
private:
std::string field1;
std::string field2;
public :
A(std::string const& s1):field1(s1){};
virtual ~A(){};
};
template<class CLIENT>
class B
{
private:
A field1;
A field2;
CLIENT field3;
public :
B(A const& a1):field1(a1){};
virtual ~B(){};
CLIENT muFunc(){return field3;};
};
int main(int argc, char** argv)
{
std::string s("s");
A a(s);
std::make_shared<B<A>>(a);
return 0;
}
when I tried to compile it, I get the following error :
main2.cc: Dans l'instanciation de « B::B(const A&) [with CLIENT = A] » :
/opt/gcc_6_3/include/c++/6.3.0/ext/new_allocator.h:120:4: requis par « void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = B; _Args = {A&}; _Tp = B] »
/opt/gcc_6_3/include/c++/6.3.0/bits/alloc_traits.h:455:4: requis par « static void std::allocator_traitsstd::allocator<_Tp1 >::construct(std::allocator_traitsstd::allocator<_Tp1 >::allocator_type&, _Up*, _Args&& ...) [with _Up = B; _Args = {A&}; _Tp = B; std::allocator_traitsstd::allocator<_Tp1 >::allocator_type = std::allocator<B >] »
/opt/gcc_6_3/include/c++/6.3.0/bits/shared_ptr_base.h:520:39: requis par « std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {A&}; _Tp = B; _Alloc = std::allocator<B >; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u] »
/opt/gcc_6_3/include/c++/6.3.0/bits/shared_ptr_base.h:615:4: requis par « std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = B; _Alloc = std::allocator<B >; _Args = {A&}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u] »
/opt/gcc_6_3/include/c++/6.3.0/bits/shared_ptr_base.h:1100:35: requis par « std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<B >; _Args = {A&}; _Tp = B; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u] »
/opt/gcc_6_3/include/c++/6.3.0/bits/shared_ptr.h:319:64: requis par « std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<B >; _Args = {A&}; _Tp = B] »
/opt/gcc_6_3/include/c++/6.3.0/bits/shared_ptr.h:619:14: requis par « std::shared_ptr<_Tp1> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = B; _Alloc = std::allocator<B >; _Args = {A&}] »
/opt/gcc_6_3/include/c++/6.3.0/bits/shared_ptr.h:635:39: requis par « std::shared_ptr<_Tp1> std::make_shared(_Args&& ...) [with _Tp = B; _Args = {A&}] »
main2.cc:37:26: requis depuis ici
main2.cc:28:28: erreur : no matching function for call to « A::A() »
B(A const& a1):field1(a1){};
^
main2.cc:14:3: note : candidate: A::A(const string&)
A(std::string const& s1):field1(s1){};
^
main2.cc:14:3: note : candidate expects 1 argument, 0 provided
main2.cc:7:7: note : candidate: A::A(const A&)
class A
^
main2.cc:7:7: note : candidate expects 1 argument, 0 provided
main2.cc:28:28: erreur : no matching function for call to « A::A() »
B(A const& a1):field1(a1){};
^
main2.cc:14:3: note : candidate: A::A(const string&)
A(std::string const& s1):field1(s1){};
^
main2.cc:14:3: note : candidate expects 1 argument, 0 provided
main2.cc:7:7: note : candidate: A::A(const A&)
class A
^
main2.cc:7:7: note : candidate expects 1 argument, 0 provided
I don't understand the error as the variable a is already created. Why does the compiler need a constructor without any paramter and how do I fix this issue.
thanks.
sorry, I just put in the class A a default constructor without any parameter and it works....

Using std::allocate_shared with polymorphic resource allocators

I am attempting to create shared pointers with a std::pmr::monotonic_buffer_resource, and I cannot make it compile. What am I missing?
https://godbolt.org/z/R9jdju
#include <memory>
#include <memory_resource>
int main() {
char buffer[100];
std::pmr::monotonic_buffer_resource mbr(buffer, 100);
std::shared_ptr<double> sp = std::allocate_shared<double>(mbr);
}
In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/ext/alloc_traits.h:34,
from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_uninitialized.h:67,
from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory:66,
from <source>:1:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/alloc_traits.h: In substitution of 'template<class _Alloc, class _Up> using __alloc_rebind = typename std::__allocator_traits_base::__rebind<_Alloc, _Up>::type [with _Alloc = std::pmr::monotonic_buffer_resource; _Up = std::_Sp_counted_ptr_inplace<double, std::pmr::monotonic_buffer_resource, __gnu_cxx::_S_atomic>]':
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:542:13: required from 'class std::_Sp_counted_ptr_inplace<double, std::pmr::monotonic_buffer_resource, __gnu_cxx::_S_atomic>'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:679:43: required from 'std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:1371:71: required from 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = double; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:408:59: required from 'std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = double]'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:859:14: required from 'std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}]'
<source>:7:66: required from here
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/alloc_traits.h:78:11: error: no type named 'type' in 'struct std::__allocator_traits_base::__rebind<std::pmr::monotonic_buffer_resource, std::_Sp_counted_ptr_inplace<double, std::pmr::monotonic_buffer_resource, __gnu_cxx::_S_atomic>, void>'
78 | using __alloc_rebind
| ^~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:52,
from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory:84,
from <source>:1:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h: In instantiation of 'std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]':
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:1371:71: required from 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = double; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:408:59: required from 'std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = double]'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:859:14: required from 'std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}]'
<source>:7:66: required from here
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:682:16: error: use of deleted function 'std::pmr::monotonic_buffer_resource::monotonic_buffer_resource(const std::pmr::monotonic_buffer_resource&)'
682 | auto __pi = ::new (__mem)
| ^~~~~~~~~~~~~
683 | _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from <source>:2:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory_resource:604:5: note: declared here
604 | monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:52,
from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory:84,
from <source>:1:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:546:33: note: initializing argument 1 of 'std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {}; _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'
546 | _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
| ~~~~~~~^~~
That long error message basically boils down to these 2 errors:
error: no type named 'type' in 'struct std::__allocator_traits_base::__rebind<std::pmr::monotonic_buffer_resource, std::_Sp_counted_ptr_inplace<double, std::pmr::monotonic_buffer_resource, __gnu_cxx::_S_atomic>, void>'
error: use of deleted function 'std::pmr::monotonic_buffer_resource::monotonic_buffer_resource(const std::pmr::monotonic_buffer_resource&)'
std::pmr::monotonic_buffer_resource does not satisfy the requirements that std::allocate_shared() expects, specifically:
All memory allocation is done using a copy of alloc, which must satisfy the Allocator requirements.
In particular, "a COPY of alloc", which fails since monotonic_buffer_resource's copy constructor is delete'd so it can't be copied.
As #MilesBudnek stated in comments, you can wrap the monotonic_buffer_resource inside a std::pmr::polymorphic_allocator, which is designed to be used as an Allocator for standard containers:
The class template std::pmr::polymorphic_allocator is an Allocator which exhibits different allocation behavior depending upon the std::pmr::memory_resource from which it is constructed.
For example:
#include <memory>
#include <memory_resource>
int main() {
char buffer[100];
std::pmr::monotonic_buffer_resource mbr(buffer, 100);
auto sp = std::allocate_shared<double, std::pmr::polymorphic_allocator<double>>(&mbr);
}
https://godbolt.org/z/-xFfFY
Alternatively:
#include <memory>
#include <memory_resource>
int main() {
char buffer[100];
std::pmr::monotonic_buffer_resource mbr(buffer, 100);
std::pmr::polymorphic_allocator<double> alloc(&mbr);
auto sp = std::allocate_shared<double>(alloc);
}
https://godbolt.org/z/GLE4-5

Strange error using a class array for a thread C++

I'm trying to do a Thread calling the cook class through a vector but I don't know to do it correctly. Here is my code:
for (int i = 0; i < _numCooks; i++) {
std::thread threadObj(this->_cooks[i].nextOrder, void);
_threads.push_back(threadObj);
}
_cooks is a vector of a class and the function that I am trying to make a thread of is:
bool cooks::nextOrder()
{
Margarita margarita(_cookOrder[0].pizzaSize);
Regina regina(_cookOrder[0].pizzaSize);
Fantasia fantasia(_cookOrder[0].pizzaSize);
Americana americana(_cookOrder[0].pizzaSize);
if (_cookOrder.empty())
return (false);
switch (_cookOrder[0].pizzaType) {
case plazza::Margarita:
return (makeOrder(margarita));
break;
case plazza::Regina:
return (makeOrder(regina));
break;
case plazza::Fantasia:
return (makeOrder(fantasia));
break;
case plazza::Americana:
return (makeOrder(americana));
break;
default:
return (false);
}
}
however when I try to compile I get this:
kitchen/kitchen.cpp: In member function ‘void
Kitchen::make_pizza(std::__cxx11::string, std::__cxx11::string, Ipc)’:
kitchen/kitchen.cpp:148:59: error: expected primary-expression before
‘void’
std::thread threadObj(this->_cooks[i].nextOrder, void);
^~~~ kitchen/kitchen.cpp:148:63: error: invalid use of non-static member
function ‘bool cooks::nextOrder()’
std::thread threadObj(this->_cooks[i].nextOrder, void);
^ In file included from kitchen/kitchen.hpp:17,
from kitchen/kitchen.cpp:5: kitchen/cooks.hpp:32:10: note: declared here
bool nextOrder();
^~~~~~~~~ In file included from /usr/include/c++/8/x86_64-redhat-linux/bits/c++allocator.h:33,
from /usr/include/c++/8/bits/allocator.h:46,
from /usr/include/c++/8/string:41,
from /usr/include/c++/8/bits/locale_classes.h:40,
from /usr/include/c++/8/bits/ios_base.h:41,
from /usr/include/c++/8/ios:42,
from /usr/include/c++/8/ostream:38,
from /usr/include/c++/8/iostream:39,
from kitchen/../pizza/IPizza.hpp:23,
from kitchen/../pizza/APizza.hpp:11,
from kitchen/kitchen.hpp:8,
from kitchen/kitchen.cpp:5: /usr/include/c++/8/ext/new_allocator.h: In instantiation of ‘void
__gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = cooks; _Args = {const cooks&}; _Tp = cooks]’: /usr/include/c++/8/bits/alloc_traits.h:475:4: required from ‘static
void std::allocator_traits
::construct(std::allocator_traits >::allocator_type&, _Up*, _Args&& ...) [with _Up = cooks; _Args = {const cooks&}; _Tp = cooks;
std::allocator_traits >::allocator_type =
std::allocator]’ /usr/include/c++/8/bits/stl_vector.h:1079:30:
required from ‘void std::vector<_Tp, _Alloc>::push_back(const
value_type&) [with _Tp = cooks; _Alloc = std::allocator;
std::vector<_Tp, _Alloc>::value_type = cooks]’
kitchen/kitchen.cpp:36:30: required from here
/usr/include/c++/8/ext/new_allocator.h:136:4: error: use of deleted
function ‘cooks::cooks(const cooks&)’ { ::new((void )__p)
_Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from kitchen/kitchen.hpp:17,
from kitchen/kitchen.cpp:5: kitchen/cooks.hpp:21:7: note: ‘cooks::cooks(const cooks&)’ is implicitly deleted because the
default definition would be ill-formed: class cooks
^~~~~ kitchen/cooks.hpp:21:7: error: use of deleted function ‘std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const
std::basic_ofstream<_CharT, _Traits>&) [with _CharT = char; _Traits =
std::char_traits]’ In file included from
kitchen/../plazza.hpp:15,
from kitchen/kitchen.hpp:13,
from kitchen/kitchen.cpp:5: /usr/include/c++/8/fstream:778:7: note: declared here
basic_ofstream(const basic_ofstream&) = delete;
^~~~~~~~~~~~~~ In file included from /usr/include/c++/8/vector:62,
from kitchen/../pizza/IPizza.hpp:24,
from kitchen/../pizza/APizza.hpp:11,
from kitchen/kitchen.hpp:8,
from kitchen/kitchen.cpp:5: /usr/include/c++/8/bits/stl_construct.h: In instantiation of ‘void
std::_Construct(_T1, _Args&& ...) [with _T1 = cooks; _Args =
{cooks}]’: /usr/include/c++/8/bits/stl_uninitialized.h:83:18:
required from ‘static _ForwardIterator
std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator; _ForwardIterator = cooks*; bool
_TrivialValueTypes = false]’ /usr/include/c++/8/bits/stl_uninitialized.h:134:15: required from
‘_ForwardIterator std::uninitialized_copy(_InputIterator,
_InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator; _ForwardIterator = cooks*]’
/usr/include/c++/8/bits/stl_uninitialized.h:289:37: required from
‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator,
_InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator; _ForwardIterator = cooks*; _Tp = cooks]’
/usr/include/c++/8/bits/stl_uninitialized.h:311:2: required from
‘_ForwardIterator
std::__uninitialized_move_if_noexcept_a(_InputIterator,
_InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = cooks*; _ForwardIterator = cooks*; _Allocator =
std::allocator]’ /usr/include/c++/8/bits/vector.tcc:447:6:
required from ‘void std::vector<_Tp,
_Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cooks&}; _Tp = cooks; _Alloc =
std::allocator; std::vector<_Tp, _Alloc>::iterator =
__gnu_cxx::__normal_iterator >; typename std::_Vector_base<_Tp, _Alloc>::pointer = cooks*]’
/usr/include/c++/8/bits/stl_vector.h:1085:4: required from ‘void
std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp =
cooks; _Alloc = std::allocator; std::vector<_Tp,
_Alloc>::value_type = cooks]’ kitchen/kitchen.cpp:36:30: required from here /usr/include/c++/8/bits/stl_construct.h:75:7: error: use of
deleted function ‘cooks::cooks(const cooks&)’
{ ::new(static_cast(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make: *** [: kitchen/kitchen.o] Error 1
Is there any way to fix it?
According to this, the first argument to a std::thread constructor should meet the Callable concept. You then pass the subsequent arguments for the Callable as additional arguments to the constructor.
You're passing a member function. You need an instance of the class to call the method on, which you're not providing. This is what this error should mean to you.
error: invalid use of non-static member function ‘bool cooks::nextOrder()’
It's probably easiest to use a lambda ie.
for (int i = 0; i < _numCooks; i++) {
_threads.emplace_back([&cook = _cooks[i]]() {
cook.nextOrder();
});
}

Strange error from move and copy constructors that have shared_ptrs

I'm getting the following errors when trying compile my HuffmanNode class for an assignment, it seems to be something to do with the shared_ptrs in the class, but I have no idea as to what is actually going wrong because of the sheer amount of text that I can't seem to find the actual problem.
g++ -std=c++11 -c src/HuffmanNode.cpp -o obj/HuffmanNode.o -I headers
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/memory:63,
from headers/HuffmanNode.hpp:9,
from src/HuffmanNode.cpp:5:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<FLNRHE001::HuffmanNode>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:637:4: required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode]’
/usr/include/c++/7/bits/shared_ptr.h:690:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
src/HuffmanNode.cpp:34:72: required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘FLNRHE001::HuffmanNode::HuffmanNode(const std::shared_ptr<FLNRHE001::HuffmanNode>&)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(FLNRHE001::HuffmanNode&&)
HuffmanNode::HuffmanNode(HuffmanNode &&n)
^~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: no known conversion for argument 1 from ‘const std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘FLNRHE001::HuffmanNode&&’
src/HuffmanNode.cpp:33:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(const FLNRHE001::HuffmanNode&)
HuffmanNode::HuffmanNode(const HuffmanNode &n)
^~~~~~~~~~~
src/HuffmanNode.cpp:33:1: note: no known conversion for argument 1 from ‘const std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘const FLNRHE001::HuffmanNode&’
src/HuffmanNode.cpp:11:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(char, int, std::shared_ptr<FLNRHE001::HuffmanNode>, std::shared_ptr<FLNRHE001::HuffmanNode>)
HuffmanNode::HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
^~~~~~~~~~~
src/HuffmanNode.cpp:11:1: note: candidate expects 4 arguments, 1 provided
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/memory:63,
from headers/HuffmanNode.hpp:9,
from src/HuffmanNode.cpp:5:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp
= FLNRHE001::HuffmanNode]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<FLNRHE001::HuffmanNode>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&};
_Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:637:4: required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode]’
/usr/include/c++/7/bits/shared_ptr.h:690:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
src/HuffmanNode.cpp:93:52: required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘FLNRHE001::HuffmanNode::HuffmanNode(std::shared_ptr<FLNRHE001::HuffmanNode>&)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(FLNRHE001::HuffmanNode&&)
HuffmanNode::HuffmanNode(HuffmanNode &&n)
^~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: no known conversion for argument 1 from ‘std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘FLNRHE001::HuffmanNode&&’
src/HuffmanNode.cpp:33:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(const FLNRHE001::HuffmanNode&)
HuffmanNode::HuffmanNode(const HuffmanNode &n)
^~~~~~~~~~~
src/HuffmanNode.cpp:33:1: note: no known conversion for argument 1 from ‘std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘const FLNRHE001::HuffmanNode&’
src/HuffmanNode.cpp:11:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(char, int, std::shared_ptr<FLNRHE001::HuffmanNode>, std::shared_ptr<FLNRHE001::HuffmanNode>)
HuffmanNode::HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
^~~~~~~~~~~
src/HuffmanNode.cpp:11:1: note: candidate expects 4 arguments, 1 provided
I've tried looking up the errors but can't seem to find anything that solves the problem.
I can't post my entire code due to it being an assignment, but the lines that are mentioned in the error text are my constructor declarations, and as stated above, the problem seems to lie in the shared_ptrs:
line 11: HuffmanNode::HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
line 33: HuffmanNode::HuffmanNode(const HuffmanNode &n) : ch(n.ch), freq(n.freq), left(std::make_shared<HuffmanNode>(n.left)), right(std::make_shared<HuffmanNode>(n.right))
line 41: HuffmanNode::HuffmanNode(HuffmanNode &&n) : ch(std::move(n.ch)), freq(std::move(n.freq)), left(std::move(n.left)), right(std::move(n.right))
EDIT:
Here's what I can post according to the school regulations, the only method that has any content inside it of the problem areas is the move constructor, and that is just ensuring that there will be no double deletion errors when the destructor is called. This gives me the same errors as above does.
#include <memory>
class HuffmanNode
{
char ch;
int freq;
std::shared_ptr<HuffmanNode> left, right;
// Node constructor for leaf node
HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
: ch(c), freq(f), left(l), right(r)
{
// Handled in initialiser list
}
HuffmanNode(const HuffmanNode &n)
: ch(n.ch), freq(n.freq), left(std::make_shared<HuffmanNode>(n.left)),
right(std::make_shared<HuffmanNode>(n.right))
{
// Handled by initialiser list
}
// Move Constructor
HuffmanNode(HuffmanNode &&n)
: ch(std::move(n.ch)), freq(std::move(n.freq)),
left(std::move(n.left)),
right(std::move(n.right))
{
}
};
The errors were arising from attempting to use make_shared to create a copy of the left and right pointers, in this case I only require a shallow copy as is made by the shared_ptr copy constructor.
The corrected solution was only a change to the move constructor as follows-:
HuffmanNode(const HuffmanNode &n)
: ch(n.ch), freq(n.freq), left(n.left),
right(n.right)
{
// Handled by initialiser list
}
Thanks to Sam Varshavchik for the help in this!

Understanding the compiler errors with std::bind

How do I get this to compile:
#include <functional>
#include <iostream>
#include <memory>
#include <string>
inline void print(std::string string1, std::string* string2)
{
std::cout << string1 << " " << string2 << std::endl;
delete string2;
}
class class1
{
public:
std::string foo{"Hello"};
std::shared_ptr<std::string> foo2;
class1();
};
class1::class1()
{
auto boundFunc = std::bind(print, foo, std::placeholders::_2);
foo2 = std::shared_ptr<std::string>(new std::string("world"), boundFunc);
}
int main()
{
class1 test;
}
GCC gives a long and cryptic bunch of error messages:
g++ -std=c++17 -o bind bind.cpp
In file included from /usr/include/c++/7.3.1/bits/shared_ptr.h:52:0,
from /usr/include/c++/7.3.1/memory:81,
from bind.cpp:21:
/usr/include/c++/7.3.1/bits/shared_ptr_base.h: In instantiation of ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Yp*, _Deleter) [with _Yp = std::__cxx11::basic_string<char>; _Deleter = std::_Bind<void (*(std::__cxx11::basic_string<char>, std::_Placeholder<2>))(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*)>; <template-parameter-2-3> = void; _Tp = std::__cxx11::basic_string<char>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’:
/usr/include/c++/7.3.1/bits/shared_ptr.h:147:48: required from ‘std::shared_ptr<_Tp>::shared_ptr(_Yp*, _Deleter) [with _Yp = std::__cxx11::basic_string<char>; _Deleter = std::_Bind<void (*(std::__cxx11::basic_string<char>, std::_Placeholder<2>))(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*)>; <template-parameter-2-3> = void; _Tp = std::__cxx11::basic_string<char>]’
bind.cpp:41:76: required from here
/usr/include/c++/7.3.1/bits/shared_ptr_base.h:1090:4: error: static assertion failed: deleter expression d(p) is well-formed
static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
^~~~~~~~~~~~~
/usr/include/c++/7.3.1/bits/shared_ptr_base.h: In instantiation of ‘std::__shared_count<_Lp>::__shared_count(_Ptr, _Deleter, _Alloc) [with _Ptr = std::__cxx11::basic_string<char>*; _Deleter = std::_Bind<void (*(std::__cxx11::basic_string<char>, std::_Placeholder<2>))(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*)>; _Alloc = std::allocator<void>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’:
/usr/include/c++/7.3.1/bits/shared_ptr_base.h:605:57: required from ‘std::__shared_count<_Lp>::__shared_count(_Ptr, _Deleter) [with _Ptr = std::__cxx11::basic_string<char>*; _Deleter = std::_Bind<void (*(std::__cxx11::basic_string<char>, std::_Placeholder<2>))(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*)>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7.3.1/bits/shared_ptr_base.h:1088:48: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Yp*, _Deleter) [with _Yp = std::__cxx11::basic_string<char>; _Deleter = std::_Bind<void (*(std::__cxx11::basic_string<char>, std::_Placeholder<2>))(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*)>; <template-parameter-2-3> = void; _Tp = std::__cxx11::basic_string<char>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7.3.1/bits/shared_ptr.h:147:48: required from ‘std::shared_ptr<_Tp>::shared_ptr(_Yp*, _Deleter) [with _Yp = std::__cxx11::basic_string<char>; _Deleter = std::_Bind<void (*(std::__cxx11::basic_string<char>, std::_Placeholder<2>))(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*)>; <template-parameter-2-3> = void; _Tp = std::__cxx11::basic_string<char>]’
bind.cpp:41:76: required from here
/usr/include/c++/7.3.1/bits/shared_ptr_base.h:623:11: error: no match for call to ‘(std::_Bind<void (*(std::__cxx11::basic_string<char>, std::_Placeholder<2>))(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*)>) (std::__cxx11::basic_string<char>*&)’
__d(__p); // Call _Deleter on __p.
~~~^~~~~
In file included from bind.cpp:19:0:
/usr/include/c++/7.3.1/functional:547:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}; _Result = _Result; _Functor = void (*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*); _Bound_args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Placeholder<2>}]
operator()(_Args&&... __args)
^~~~~~~~
/usr/include/c++/7.3.1/functional:547:2: note: template argument deduction/substitution failed:
/usr/include/c++/7.3.1/functional:558:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _Result = _Result; _Functor = void (*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*); _Bound_args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Placeholder<2>}]
operator()(_Args&&... __args) const
^~~~~~~~
/usr/include/c++/7.3.1/functional:558:2: note: template argument deduction/substitution failed:
/usr/include/c++/7.3.1/functional:576:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}; _Result = _Result; _Functor = void (*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*); _Bound_args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Placeholder<2>}]
operator()(_Args&&... __args) volatile
^~~~~~~~
/usr/include/c++/7.3.1/functional:576:2: note: template argument deduction/substitution failed:
/usr/include/c++/7.3.1/functional:588:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}; _Result = _Result; _Functor = void (*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*); _Bound_args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Placeholder<2>}]
operator()(_Args&&... __args) const volatile
^~~~~~~~
/usr/include/c++/7.3.1/functional:588:2: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7.3.1/bits/shared_ptr.h:52:0,
from /usr/include/c++/7.3.1/memory:81,
from bind.cpp:21:
/usr/include/c++/7.3.1/bits/shared_ptr_base.h: In instantiation of ‘void std::_Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp>::_M_dispose() [with _Ptr = std::__cxx11::basic_string<char>*; _Deleter = std::_Bind<void (*(std::__cxx11::basic_string<char>, std::_Placeholder<2>))(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*)>; _Alloc = std::allocator<void>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’:
bind.cpp:47:1: required from here
/usr/include/c++/7.3.1/bits/shared_ptr_base.h:470:25: error: no match for call to ‘(std::_Bind<void (*(std::__cxx11::basic_string<char>, std::_Placeholder<2>))(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*)>) (std::__cxx11::basic_string<char>*&)’
{ _M_impl._M_del()(_M_impl._M_ptr); }
~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
In file included from bind.cpp:19:0:
/usr/include/c++/7.3.1/functional:547:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}; _Result = _Result; _Functor = void (*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*); _Bound_args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Placeholder<2>}]
operator()(_Args&&... __args)
^~~~~~~~
/usr/include/c++/7.3.1/functional:547:2: note: template argument deduction/substitution failed:
/usr/include/c++/7.3.1/functional:558:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _Result = _Result; _Functor = void (*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*); _Bound_args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Placeholder<2>}]
operator()(_Args&&... __args) const
^~~~~~~~
/usr/include/c++/7.3.1/functional:558:2: note: template argument deduction/substitution failed:
/usr/include/c++/7.3.1/functional:576:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}; _Result = _Result; _Functor = void (*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*); _Bound_args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Placeholder<2>}]
operator()(_Args&&... __args) volatile
^~~~~~~~
/usr/include/c++/7.3.1/functional:576:2: note: template argument deduction/substitution failed:
/usr/include/c++/7.3.1/functional:588:2: note: candidate: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}; _Result = _Result; _Functor = void (*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>*); _Bound_args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Placeholder<2>}]
operator()(_Args&&... __args) const volatile
^~~~~~~~
/usr/include/c++/7.3.1/functional:588:2: note: template argument deduction/substitution failed:
I'm not sure what to make of this output, and I haven't found any good documentation of std::bind which provides examples for all the various ways in which it might be used, only the most basic cases.
stackoverflow wants more details, but I don't even know what else to provide. It should be obvious from the code what the problem is. If I knew what to say I would be able to search for it already, but I'm not sure how to describe this problem.
Simple fix: Replace
auto boundFunc = std::bind(print, foo, std::placeholders::_2);
with
auto boundFunc = std::bind(print, foo, std::placeholders::_1);
Why?
In std::bind, the placeholders indicate the index of the argument to the result function. std::placeholders::_1 means "use the first argument passed to me in this position".
When you pass std::placeholders::_2, your boundFunc will take the wrong number of arguments (2 instead of 1) and no longer be a valid deleter for an std::shared_ptr.
The error is subtle but there. You probably used std::placeholders::_2 because you are using the second argument, right? Well, that's not how you use them.
The number _N designates that the argument number N (when you call the result) is bound to _N. In other words, you need to enumerate them from 1 onwards in your case:
auto boundFunc = std::bind(print, foo, std::placeholders::_1);
// ^