简体   繁体   English

c++17 的 std::ptr_fun 替换

[英]std::ptr_fun replacement for c++17

I am using std::ptr_fun as follows:我使用std::ptr_fun如下:

static inline std::string &ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
    return s;
}

as presented in this answer .本答案中所述

However this does not compile with C++17 (using Microsoft Visual Studio 2017), with the error:但是,这不能使用 C++17(使用 Microsoft Visual Studio 2017)编译,并出现错误:

error C2039: 'ptr_fun': is not a member of 'std'

How can this be fixed?如何解决这个问题?

You use a lambda:您使用 lambda:

static inline std::string &ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) {return !std::isspace(c);}));
    return s;
}

The answer you cited is from 2008, well before C++11 and lambdas existed.您引用的答案是 2008 年的,早在 C++11 和 lambdas 出现之前。

Just use a lambda:只需使用 lambda:

[](unsigned char c){ return !std::isspace(c); }

Note that I changed the argument type to unsigned char , see the notes for std::isspace for why.请注意,我将参数类型更改为unsigned char ,请参阅std::isspace注释了解原因。

std::ptr_fun was deprecated in C++11, and will be removed completely in C++17. std::ptr_fun在 C++11 中被弃用,并将在 C++17 中完全删除。

According to cppreference , std::ptr_fun is deprecated since C++11 and discontinued since C++17.根据cppreferencestd::ptr_fun自 C++11 起已弃用,自 C++17 起停产。

Similarly, std::not1 is deprecated since C++17.类似地,自 C++17 起不推荐使用std::not1

So best don't use either, but a lambda (as explained in other answers).所以最好不要使用任何一个,而是使用 lambda(如其他答案中所述)。

Alternatively, you might use std::not_fn :或者,您可以使用std::not_fn

static inline std::string &ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(),
        std::not_fn(static_cast<int(*)(int)>(std::isspace))));
    return s;
}

My answer is similar to the already given answers in this thread.我的答案类似于该线程中已经给出的答案。 But instead of但不是

int isspace(int c);

function from the standard C library, I am suggesting to use来自标准C库的函数,我建议使用

bool isspace(char c, const locale& loc);

function instantiation from the standard C++ library ( http://en.cppreference.com/w/cpp/locale/isspace ), which is more type-correct.来自标准C++库 ( http://en.cppreference.com/w/cpp/locale/isspace ) 的函数实例化,它的类型更正确。 In this case you don't need to think about char -> unsigned char -> int conversions and about the current user's locale.在这种情况下,您无需考虑char -> unsigned char -> int转换以及当前用户的语言环境。

The lambda which searches for non-space will looks like this then:搜索非空间的 lambda 将如下所示:

[](char c) { return !std::isspace(c, std::locale::classic()); }

And the full code of ltrim function will look like this: ltrim函数的完整代码如下所示:

static inline std::string& ltrim(std::string& s) {
    auto is_not_space = [](char c) { return !std::isspace(c, std::locale::classic()); };
    auto first_non_space = std::find_if(s.begin(), s.end(), is_not_space);
    s.erase(s.begin(), first_non_space);
    return s;
}

You use Lambda as suggested by Nicol Bolas but you can use auto and type will be deduced there, as follow:-您按照 Nicol Bolas 的建议使用 Lambda,但您可以使用 auto 并在那里推断出类型,如下所示:-

    static inline std::string &ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](auto c) {return 
       !std::isspace(c);}));
    return s;
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM