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);
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);
// ^
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.