2015-06-13 9 views
5
transform(mystr.begin(), mystr.end(), mystr.begin(), tolower); 

Sto usando la funzione di trasformazione per trasformare una stringa in tutte le lettere minuscole, ma anche dopo aver scritto "using namespace std;" nella parte superiore del mio programma ottengo un sacco di errori (quando scritto come sopra). Quando includo l'operatore :: prima del parametro tolower (come di seguito) non lo faccio. Perchè è questo? Pensavo che la funzione tolower fosse nello spazio dei nomi std e funzionasse come sopra.:: operatore necessario per usare con tolower()?

transform(mystr.begin(), mystr.end(), mystr.begin(), ::tolower); 

ho la seguente include:

#include <iostream> 
#include <fstream 
#include <sstream> 
#include <algorithm> 
#include <vector> 

Nel messaggio di errore vedo:

error: no matching function for call to 'transform(std::basic_string<char>::iterator, ... 

allora il luogo in cui 'tolower' è nella lista dei parametri

, <unresolved overloaded function type>);' 
+5

Quando hai "un sacco di errori" è utile dire esattamente quello che sono. –

risposta

3

:: vuol dire che è nello spazio dei nomi globale. Rende solo chiaro

4

Qual è il file di intestazione che hai incluso? Assicurati di includere <cctype> e non <ctype.h> .. Nel <cctype> tutte le funzioni sono state definite nello std del namespace.

6

E 'per risolvere il conflitto tra i sovraccarichi di tolower tra <cctype> 's int tolower(int c) e <locale>' s modello <typename charT> charT tolower(charT c, locale const& loc)

::tolower utilizzare quella di portata globale

+1

... e la soluzione è lanciare 'tolower' nel tipo appropriato, che costringerà la risoluzione:' static_cast (tolower) ' – davmac

+1

(anche se come sottolinea Matt McNabb, non è abbastanza corretta). – davmac

6

Bene, questo è un po' complicato. L'aggiunta di #include <cctype> probabilmente sembra risolvere il tuo problema. Tuttavia c'è un po 'di più in corso.

ci sono queste due versioni di tolower:

int std::tolower(int ch);       // #include <cctype> 

template<typename charT> 
charT std::tolower(charT ch, const std::locale& loc); // #include <locale> 

, ma ci possono essere anche questa versione:

int ::tolower(int ch); // #include <cctype> or #include <ctype.h> 

perché le implementazioni sono autorizzati a iniettare nomi dalla std nel namespace globale. Inoltre, non puoi contare su cctype o locale incluso o meno, perché qualsiasi standard include anche qualsiasi altro standard incluso.


Sembra che avete intenzione di utilizzare la versione da <cctype>. Tuttavia, sarebbe un bug. Se si controlla la documentazione per quella versione di tolower, si vedrà che l'argomento deve essere convertito in unsigned char prima di essere passato alla funzione.

IOW, passando a char con valore negativo alla versione di cctype di tolower causa un comportamento non definito. (Anche se le implementazioni comuni lo supportano perché è un errore così comune).

Per correggere il codice e ancora utilizzare la versione cctype, si potrebbe scrivere:

#include <cctype> 

// ... 

transform(mystr.begin(), mystr.end(), mystr.begin(), 
    [](char ch) { return std::tolower((unsigned char)ch); }); 

anche se sembra un po 'più semplice da usare:

for (char &ch : mystr) 
    ch = std::tolower((unsigned char)ch); 

La versione <locale> sarebbe simile (ricordando che è un modello di funzione):

#include <locale> 
#include <functional> 

// ... 

transform(mystr.begin(), mystr.end(), mystr.begin(), 
    std::bind(std::tolower<char>, std::placeholders::_1, std::locale())); 

o

std::locale loc; 

for (char &ch : mystr) 
    ch = std::tolower(ch, loc); 
Problemi correlati