webentwicklung-frage-antwort-db.com.de

std :: ptr_fun ersatz für c ++ 17

Ich benutze std::ptr_fun wie folgt:

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;
}

wie in diese Antwort dargestellt .

Dies wird jedoch nicht mit C++ 17 (mit Microsoft Visual Studio 2017) mit dem Fehler kompiliert:

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

Wie kann das behoben werden?

8
user3717478

Sie verwenden ein 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;
}

Die Antwort, die Sie zitieren, stammt aus dem Jahr 2008, lange bevor C++ 11 und Lambdas existierten.

20
Nicol Bolas

Verwenden Sie einfach ein Lambda:

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

Beachten Sie, dass ich den Argumenttyp in unsigned char geändert habe. Die Gründe dafür finden Sie in den Hinweisen zu std::isspace

std::ptr_fun wurde in C++ 11 nicht mehr unterstützt und wird in C++ 17 vollständig entfernt. 

14
Barry

Gemäß cppreference ist std::ptr_fun seit C++ 11 veraltet und seit C++ 17 nicht mehr verfügbar.

Ähnlich ist std::not1 seit C++ 17 veraltet.

Verwenden Sie also am besten auch keine, sondern ein Lambda (wie in anderen Antworten erläutert).

3
Walter

Alternativ können Sie std :: not_fn verwenden:

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;
}
2
Edgar Rokjān

Meine Antwort ist der Antwort von Barry ähnlich ( https://stackoverflow.com/a/44973511/1016580 ).

Anstatt 

int isspace(int c);

funktion aus der Standardbibliothek C können Sie verwenden

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

funktionsinstanziierung aus der Standardbibliothek C++ ( http://en.cppreference.com/w/cpp/locale/isspace ), was typgerechter ist. In diesem Fall müssen Sie nicht über char -> unsigned char -> int-Konvertierungen und das Gebietsschema des aktuellen Benutzers nachdenken.

Das resultierende Lambda sieht dann so aus:

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