c – 为什么不能将mem_fn应用于std :: string的成员函数?

struct int_holder {
    int value;
    int triple() {return value*3;}
};

int main(int argc, const char * argv[])
{
    std::string abc{"abc"};
    int_holder one{1};

    auto f1 = mem_fn(&std::string::clear);
    auto f2 = mem_fn(&int_holder::triple);
    f1(abc);
    f2(one);
}

我在Xcode中测试这样的代码,编译器发出这样的错误

似乎mem_fn对于用户定义的类的成员函数没有问题,但是没有标准字符串的成员函数,有什么不同,为什么?
谢谢你的阅读,帮助我PLZ!

最佳答案 至于标准,你不能指向任何标准的非静态成员,因为允许库实现添加隐藏的重载,默认的函数模板参数,返回类型的SFINAE等.

换句话说,& std :: string :: clear根本不是受支持的操作.

就Clang而言,它看起来像隐藏符号可见性的问题.每个共享对象(链接器输出)文件都有自己的某些函数副本,以避免第三方共享库实现标准库的外观.随着不同的副本浮动,PTMF上的相等运算符将无法工作:如果保留值& std :: string :: clear来自内联函数,以后它可能不会比较等于它自己.但是,它可能是一个错误,因为std :: string应该由libc .so共享库完全实现.只有std :: basic_string的其他特化才能证明这种行为是正确的.

一个很好的解决方法是使用lambda代替. [](std :: string& o){o.clear(); }是mem_fn的优秀替代品.它避免了间接调用,其sizeof更小.实际上,除非绝对必要,否则不应使用mem_fn.

点赞