1

我如何让它编译:

#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 给出了一长串神秘的错误信息:

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:

我不确定如何处理这个输出,也没有找到任何关于 std::bind 的好的文档,它提供了所有可能使用它的各种方式的示例,只有最基本的情况。

stackoverflow 想要更多细节,但我什至不知道还能提供什么。从代码中应该很明显问题是什么。如果我知道该说什么,我就可以搜索它了,但我不确定如何描述这个问题。

4

2 回答 2

4

简单修复:替换

auto boundFunc = std::bind(print, foo, std::placeholders::_2);

auto boundFunc = std::bind(print, foo, std::placeholders::_1);

为什么?

std::bind中,占位符指示结果函数的参数索引。std::placeholders::_1意思是“使用在这个位置传递给我的第一个参数”。

当您通过 时std::placeholders::_2,您boundFunc将采用错误数量的参数(2 而不是 1)并且不再是std::shared_ptr.

于 2018-05-13T12:58:09.880 回答
2

错误很微妙,但在那里。您可能使用std::placeholders::_2了,因为您使用的是第二个参数,对吧?好吧,这不是你使用它们的方式。

数字 _N 表示参数编号 N(当您调用结果时)绑定到 _N。换句话说,在您的情况下,您需要从 1 开始枚举它们:

auto boundFunc = std::bind(print, foo, std::placeholders::_1);
//                                                         ^
于 2018-05-13T12:57:27.427 回答