Was bedeutet das “::” in “::tolower”?

Lesezeit: 4 Minuten

Benutzer-Avatar
VextoR

Ich habe Code wie diesen gesehen:

std::string str = "wHatEver";
std::transform(str.begin(), str.end(), str.begin(), ::tolower);

Und ich habe eine Frage: was bedeutet :: vor Tolower?

und std::tolower funktioniert nicht, aber ::tolower funktioniert in Ordnung

  • Technisch heißt es Oszilloskopauflösungsoperator. Das sollte Ihnen einen Begriff geben, um Ihre Suche nach weiteren Details zu beginnen.

    – Cody Grey

    11. März 2011 um 9:00 Uhr


Benutzer-Avatar
James Kanze

Warum die :: notwendig: Der Standard definiert zwei tolower‘s, eine Funktionsvorlage in std::und eine einfache Funktion in beiden :: und
std::. Je nachdem, welche Kopfzeilen eingefügt wurden (und dazu gehören Kopfzeilen, die indirekt von anderen Kopfzeilen eingefügt wurden, von denen Sie möglicherweise nichts wissen), kann entweder die eine, die andere oder beide sichtbar sein. Verwenden :: stellt sicher, dass der ältere aus dem C-Standard verwendet wird. (Falls der drin ist std::
berücksichtigt wird, ist der Aufruf mehrdeutig, da transform selbst eine Vorlage ist und der Compiler die Vorlagenargumente nicht ableiten kann.)

Wenn ich schon dabei bin, könnte ich das mit erwähnen ::tolower Dies ist ein undefiniertes Verhalten, zumindest wenn ein einfaches Zeichen signiert ist. Die Eingabe zu
::tolower ist ein int und muss im Bereich liegen 0UCHAR_MAXoder EOF. Wenn einfaches Zeichen signiert ist, können einige der Zeichen negative Codierungen haben, was zu undefiniertem Verhalten führt. In der Praxis funktioniert dies bei den meisten Implementierungen. Für alle Charaktere außer 0xFF (ÿ in Latein 1). Wenn Sie sich nicht mit Portabilität befassen, haben einige Compiler einen Schalter, um char unsigned zu machen – verwenden Sie ihn. Schreiben Sie andernfalls ein kleines funktionales Objekt, um es korrekt zu handhaben, entweder:

struct ToLower
{
    char operator()( char ch ) const
    {
        return ::tolower( static_cast<unsigned char>(ch) );
    }
};

oder (besser, aber wesentlich arbeitsaufwändiger – lohnt sich nur, wenn Sie es häufig verwenden), ein funktionales Objekt, dessen Konstruktor ein Gebietsschema übernimmt (standardmäßig das globale Gebietsschema) und einen Verweis auf eine enthält std::ctypedie es für die verwendet tolower Funktion. (Natürlich, wenn Sie wirklich internationalisiert sind, tolower hat wohl keine bedeutung. Und Sie verwenden UTF-8, eine Multibyte-Codierung, die mit keiner der verfügbaren Möglichkeiten funktioniert.)

Benutzer-Avatar
EboMike

Bedeutet, dass es explizit die verwendet tolower im globalen Namensraum (der vermutlich der stdc lib ist).

Beispiel:

void foo() {
    // This is your global foo
}

namespace bar {
    void foo() {
        // This is bar's foo
    }
}

using namespace bar;

void test() {
    foo();   // Ambiguous - which one is it?
    ::foo(); // This is the global foo()
}

  • danke, aber ich kann nicht verstehen, du hast geschrieben – using namespace bar; Warum verwendet der Compiler nicht foo from bar? warum Sie bar::foo schreiben müssen, nachdem Sie den Namensraum bar verwendet haben; Kannst du bitte Erklären?

    – VextoR

    11. März 2011 um 9:09 Uhr

  • “Namespace-Leiste verwenden” bedeutet das foo() von selbst impliziert bar::foo(). Aber vielleicht wollten Sie die verwenden foo() im globalen Rahmen? Das geht auch über foo(). So foo() könnte für beides verwendet werden. Jetzt ist der Compiler nicht sicher, welchen Sie gemeint haben, also müssen Sie ihn angeben.

    – EboMike

    11. März 2011 um 9:11 Uhr

  • @EboMike “foo() von selbst impliziert bar::foo()” ist zu stark. Namenssuche berücksichtigt bar::foo bei der Suche nach einer Übereinstimmung für foo (und findet in diesem Fall Mehrdeutigkeit mit ::foo)

    – Caleth

    12. Juli 2018 um 14:17 Uhr

Verwenden Sie die Version aus dem globalen Namensraum. (Wahrscheinlich enthalten <ctypes.h> und nicht <cctypes> wenn std:: geht nicht)

  • Vielen Dank. Ich verwende Visual C++ 6. :: sagt also, dass tolower aus dem globalen Namespace verwendet werden soll

    – VextoR

    11. März 2011 um 8:54 Uhr


  • Ja, die andere potenzielle Überlastung von tolower ist drin <locale> (Ich sagte Potenzial, weil ich nicht weiß, wie konform VC++6 in diesem Punkt ist … warum einen so alten Compiler verwenden?)

    – Ein Programmierer

    11. März 2011 um 9:00 Uhr

  • “Warum einen so alten Compiler verwenden?” Oh, frag nicht)) Es liegt an einem sehr alten Projekt

    – VextoR

    11. März 2011 um 9:02 Uhr

  • Das ist der einzig gültige Grund (aber ich würde einen Wechsel einplanen, wenn das Projekt fortgesetzt werden muss). Wir sehen viel zu viele Lernende, die es immer noch verwenden.

    – Ein Programmierer

    11. März 2011 um 9:08 Uhr

:: ist der globale Namespace.

#include <iostream>

void bar()
{
    std::cout << "::bar" << std::endl;
}

namespace foo
{
    void bar()
    {
        std::cout << "foo::bar" << std::endl;
    }
}

int main()
{
    bar();
    foo::bar();
    ::bar();
    using namespace foo;
    foo::bar();
    ::bar(); // bar() would be ambiguous now without ::
}

1015840cookie-checkWas bedeutet das “::” in “::tolower”?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy