std::ptr_fun replacement for c++17

后端 未结 6 2121
無奈伤痛
無奈伤痛 2021-02-04 00:11

I am using std::ptr_fun as follows:

static inline std::string <rim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(         


        
相关标签:
6条回答
  • 2021-02-04 00:30

    You use a 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.

    0 讨论(0)
  • 2021-02-04 00:31

    According to cppreference, std::ptr_fun is deprecated since C++11 and discontinued since C++17.

    Similarly, std::not1 is deprecated since C++17.

    So best don't use either, but a lambda (as explained in other answers).

    0 讨论(0)
  • 2021-02-04 00:38

    Just use a 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.

    std::ptr_fun was deprecated in C++11, and will be removed completely in C++17.

    0 讨论(0)
  • 2021-02-04 00:39

    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

    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. In this case you don't need to think about char -> unsigned char -> int conversions and about the current user's locale.

    The lambda which searches for non-space will looks like this then:

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

    And the full code of ltrim function will look like this:

    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;
    }
    
    0 讨论(0)
  • 2021-02-04 00:40

    Alternatively, you might use 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;
    }
    
    0 讨论(0)
  • 2021-02-04 00:48

    You use Lambda as suggested by Nicol Bolas but you can use auto and type will be deduced there, as follow:-

        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;
      }
    
    0 讨论(0)
提交回复
热议问题