std::tolower
in C++ überlastet ist, wird es in <cctype>
erklärt als
int tolower(int);
und auch in <locale>
als
template<CharT> CharT tolower(CharT, const locale&);
so, wenn Sie sagen "std::tolower
" Sie einen mehrdeutigen Verweis auf eine bekommen überladene Funktion.
- Warum
::tolower
Version funktioniert?
Wenn Sie <cctype>
die einargumentigen Überlastung enthalten ist std
in Namensbereich deklariert und könnte auch im globalen Namensraum deklariert werden, auf dem Compiler abhängig. Wenn Sie <ctype.h>
einschließen, ist es garantiert, dass es im globalen Namespace enthalten ist, und ::tolower
wird funktionieren (obwohl Dietmars Punkte darüber, wann es nicht sicher ist) beachten. Die Zwei-Argument-Überladung von <locale>
wird nie im globalen Namespace deklariert, so dass sich ::tolower
niemals auf die Zwei-Argument-Überladung bezieht.
2. Warum funktioniert std::tolower
nicht in std :: transform?
Siehe oben, es ist ein überladener Name.
3. Was versucht static_cast<int(*)(int)>(std::tolower))
wirklich zu tun?
Es teilt dem Compiler Sie die int std::tolower(int)
Überlastung wollen, keine andere Überlastung von std::tolower
.
Warum funktioniert es mit GCC und nicht mit Visual Studio 2013?
Wahrscheinlich, weil Sie umfaßte nicht <cctype>
, oder (weniger wahrscheinlich) einen Visual Studio Fehler sein könnte.
4.Wie könnte ich std::lower
in std::transform
mit Visual Studio 2013 dann verwenden?
Wenn Sie wissen, dass Sie nur Zeichen mit Werten zwischen 0 und 127 haben, dann können Sie <ctype.h>
umfassen und ::tolower
verwenden (da die zweiargumentigen Version im globalen Namespace nicht deklariert wird, nur im Namensraum std
) oder disambiguate die überladen Sie mit dem statischen Cast. Eine Alternative zu der Umwandlung ist eine lokale Variable zu verwenden:
typedef int (*tolower_type)(int);
tolower_type tl = &std::tolower;
std::transform(b, e, b, tl);
eine sicherere und tragbare Alternative ist, ein Objekt benutzerdefinierte Funktion zu verwenden (oder Lambda-Ausdruck) sicher die gewünschte Überlastung zu nennen:
std::transform(b, e, b, [](unsigned char i) { return std::tolower(i); });
Dies verwendet std::tolower
mit einem Argument, sodass der Compiler eine Überladungsauflösung ausführen kann, um zu ermitteln, welche Überladung Sie aufrufen möchten. Der Parameter ist unsigned char
, um sicherzustellen, dass wir nie einen char
mit einem negativen Wert an tolower(int)
übergeben, weil das undefiniertes Verhalten hat.
Weitere Informationen finden Sie unter http://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.simple.
Haben Sie versucht, einschließlich der '' Header, [wo ist 'std :: tolower' tatsächlich definiert ist] (http://en.cppreference.com/w/cpp/string/byte/tolower)? –
oups, Oo '^^ Aber warum funktioniert es dann mit GCC? – Korchkidu
@Korchkidu, denn mit GCC gehört zu einem der anderen Header, die Sie eingeschlossen haben, ''. Verwechseln Sie nie "es passiert, dass es mit einem Compiler funktioniert", was bedeutet, dass der Code tatsächlich korrekt ist, insbesondere in Bezug auf Header, die intern auch andere Header der Library enthalten. –