c++ - 如何存储从 std::bind 返回的可调用对象以获取指向成员函数的指针?

标签 c++ c++11 pointer-to-member stdbind

我想知道如何声明一个返回类型为std::function的对象与指向成员函数的指针一起使用时:

int main(){

    void foo(std::string, int);
    string s = "hi";
    auto fn = std::bind(foo, s, std::placeholders::_1);
    fn(5);// ok

    /*auto fn2 = */std::bind(&std::string::empty, std::placeholders::_1); // error if I uncomment /*auto fn2 = */

    std::vector<std::string> vs{"The", "Quick", "Brown", "Fox", "Jumped", "", "Over", "The", "", "Lazy", "Dog"};
    auto it = std::find_if(vs.cbegin(), vs.cend(),
    std::bind(&std::string::empty, std::placeholders::_1)); // OK
    std::cout << "Empty string found at index: " << (it != vs.cend() ? std::distance(vs.cbegin(), it) : -1) << '\n'; // 5

    std::cout << "\ndone!\n";
}
  • 如果我取消评论 auto fn2 = 我收到一个错误:

||=== Build: Debug in myproj (compiler: GNU GCC Compiler) ===| /home/Itachi57/Desktop/myproj/main.cxx||In function ‘int main()’:| /home/Itachi57/Desktop/myproj/main.cxx|845| in ‘constexpr’ expansion of ‘std::bind(_Func&&, _BoundArgs&& ...) [with _Func = bool (std::__cxx11::basic_string<char>::*)() const noexcept; _BoundArgs = {const std::_Placeholder<1>&}; typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type = std::_Bind_helper<false, bool (std::__cxx11::basic_string<char>::*)() const noexcept, const std::_Placeholder<1>&>::type](std::placeholders::_1)’| /home/Itachi57/Desktop/myproj/main.cxx|845|internal compiler error: Segmentation fault| ||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 7 second(s)) ===|

  • 如果我调用 bind 为什么?不使用 auto 存储其返回值将指针绑定(bind)到成员函数时可以,但我无法存储该值(新可调用)?

  • 事实上,这只是为了练习目的,因为实际上我更喜欢使用 std::mem_fnstd::function .

  • 更新:

如果我从终端运行程序:

  g++ main.cxx -std=c++2a -o prog && ./prog

效果很好。

我发现有一天我从 CodeBlocks 中禁用了“复制省略优化”:

 -fno-elide-constructors 

现在,如果我删除它并让 CodeBlocks 应用它(复制省略选项。)程序构建并运行得很好!

  • 那么这个错误与复制省略优化有关系吗?谢谢!

最佳答案

// error if I uncomment /*auto fn2 = */
// OK

实际上,不,这不好。 C++ 标准通常不允许获取命名空间 std 中定义的函数的地址(无论是自由函数还是成员函数)。异常总是被显式标记为可寻址函数,并且 std::string::empty 是不可寻址的。

为什么?实现余地和 future 证明。该标准可能想要添加重载。 实现可能想要使用重载来实现标准强制行为,甚至是模板。为了实现这一点,并且我们的程序被标准很好地定义,我们不能这样做 &std::string::empty

只需使用 lambda 来包装不可寻址的标准函数(就像您使用自己的重载集一样)。实际上......只需使用 lambdas 并忘记 std::bind,它们几乎在各个方面都更好。

关于c++ - 如何存储从 std::bind 返回的可调用对象以获取指向成员函数的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69817650/

相关文章:

c++ - OpenGL - 统一未正确传递?

c++ - 设置 packaged_task 的正确方法

C++ 指针成员函数与模板赋值与另一个类的成员函数

c++ - 指向虚拟成员函数的指针

c++ - 只需要知道我在c++中打印模式的方式是否有效,或者还有另一种方式可以有效地进行打印

c++ - 从 .exe 获取编译日期和时间

c++ - 使用字符串流解码十六进制编码的字符串

c++ - 默认的 Move 构造函数是否定义为 noexcept?

C++ thread_id 是什么数据类型,它可以分配给变量吗?

c++ - C++ 中的回调,模板成员? (2)