web-dev-qa-db-fra.com

std :: ptr_fun remplacement pour c ++ 17

J'utilise std::ptr_fun comme suit:

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

tel que présenté dans cette réponse .

Toutefois, cela ne compile pas avec C++ 17 (à l'aide de Microsoft Visual Studio 2017), avec l'erreur suivante:

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

Comment cela peut-il être corrigé?

8
user3717478

Vous utilisez un 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;
}

La réponse que vous avez citée date de 2008, bien avant que C++ 11 et lambdas n'existent.

20
Nicol Bolas

Il suffit d'utiliser un lambda:

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

Notez que j'ai changé le type d'argument en unsigned char, voir les notes pour std::isspace for pourquoi. 

std::ptr_fun était obsolète en C++ 11 et sera complètement supprimé en C++ 17. 

14
Barry

Selon cppreference , std::ptr_fun est obsolète depuis C++ 11 et abandonné depuis C++ 17.

De même, std::not1 est obsolète depuis C++ 17.

Il vaut donc mieux ne pas utiliser non plus, mais un lambda (comme expliqué dans d'autres réponses).

3
Walter

Vous pouvez également utiliser 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;
}
2
Edgar Rokjān

Ma réponse est similaire à la réponse de Barry ( https://stackoverflow.com/a/44973511/1016580 ).

Au lieu de 

int isspace(int c);

fonction de la bibliothèque C standard, vous pouvez utiliser

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

instanciation de fonction à partir de la bibliothèque standard C++ ( http://fr.cppreference.com/w/cpp/locale/isspace ), qui est davantage typée. Dans ce cas, vous n'avez pas besoin de penser aux conversions char -> unsigned char -> int ni aux paramètres régionaux de l'utilisateur actuel.

Le lambda résultant ressemble à ceci:

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