2016-06-26 29 views
6

Il mio codice:errore di compilazione: 'stoi' non è un membro di 'std'

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string test = "45"; 
    int myint = std::stoi(test); 
    std::cout << myint << '\n'; 
} 

mi dà l'errore di compilazione:

error: 'stoi' is not a member of 'std' 
    int myint = std::stoi(test); 
       ^

Tuttavia, secondo here, questo codice dovrebbe compilare bene. Sto usando la linea set(CMAKE_CXX_FLAGS "-std=c++11 -O3") nel mio file CMakeLists.txt.

Perché non si sta compilando?


Update: Sto usando gcc, e l'esecuzione di gcc --version stampe out:

gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010 
+0

Non hai specificato quale versione del compilatore stai usando. –

+0

Guarda questa discussione http://www.cplusplus.com/forum/beginner/120836/ – jonathanGB

+0

@CaptainObvlious, sto usando gcc versione 5.2.1 – Karnivaurus

risposta

2

La versione sembra fino ad oggi, quindi non dovrebbe essere un problema. Penso che potrebbe essere correlato a gcc. Prova invece il g++. (Molto probabilmente il problema di collegamento automatico. Se esegui gcc su un file C++, non funzionerà come fa g ++. Questo perché non si collegherà automaticamente alla libreria std C++, ecc.). Il mio secondo consiglio è provare std::atoi.

@ Ho risolto il problema. std::stoi utilizza libstdC++. Si tratta di La libreria GNU Standard C++. In gcc devi aggiungere il numero -lstdc++. Tuttavia, in g ++, il comando libstdC++ viene collegato automaticamente a . using gcc e using g++

Prestare attenzione come viene compilato

usando g ++: g++ -std=c++11 -O3 -Wall -pedantic main.cpp && ./a.out

usando gcc: gcc -std=c++11 -O3 -Wall -pedantic -lstdc++ main.cpp && ./a.out

penso che si dovrebbe impostare il flag come set(CMAKE_EXE_LINKER_FLAGS "-libgcc -lstdc++") (non testato)

#include <cstdlib> 

int myInt = std::atoi(test.c_str()); 
+0

Grazie - usando 'std :: atoi' ha funzionato per me. Anche se non sono ancora sicuro del problema sottostante con 'std :: stoi' ... – Karnivaurus

+1

@Karnivaurus Il problema ha a che fare con il collegamento nella libreria standard C++. Con il comando 'gcc', devi farlo manualmente con qualcosa come' -lstdC++ 'ma' g ++' si collegherà automaticamente a questo per te. [Esempio] (http://coliru.stacked-crooked.com/a/805d20d69f46d8d8) – VermillionAzure

+0

@Vermilion: se ha funzionato bene con atoi, non si tratta di un errore di collegamento. Come l'errore ha detto in primo luogo, è che le funzioni non sono state dichiarate nell'intestazione, perché sono state rimosse dal preprocessore. Questo non ha nulla a che fare con i comandi di collegamento o 'gcc' vs' g ++ '. – Kundor

8

In libstdC++, il de finitions di stoi, stol, ecc, nonché le to_string funzioni, sono custoditi dalla condizione

#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ 
    && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) 

Ho avuto questo sicuro su una piattaforma prima (cioè Termux su Android), con conseguente to_string non essere disponibile anche con g ++ 6.1 e lo standard C++ 14. In questo caso, ho appena fatto

#define _GLIBCXX_USE_C99 1 

prima di includere qualsiasi cosa, e voilà, improvvisamente le funzioni esistesse. (Si dovrebbe mettere questo primo, o anche sulla riga di comando, e non solo prima di includere <string>, perché un altro colpo di testa può includere <string> prima, e poi le sue sono le protezioni per impedire che mai vedere la macro.)

ho fatto non indagare sul motivo per cui questa macro non è stata impostata in primo luogo. Ovviamente questo è motivo di preoccupazione se vuoi che il tuo codice funzioni effettivamente (nel mio caso non l'ho fatto in modo particolare, ma FWIW non ci sono stati problemi.)

Si dovrebbe verificare se _GLIBCXX_USE_C99 non è definito, o se _GLIBCXX_HAVE_BROKEN_VSWPRINTFè definito (che può essere il caso in MinGW?)

+0

libstdC++ umm il problema dell'OP è sicuramente correlato a 'gcc'. Deve usare 'g ++'. Poiché Rup (un utente SO) dice che gcc selezionerà il compilatore back-end corretto basato sull'estensione del file (cioè compilerà un file .c come C e un .cc come C++) e collegherà i binari solo alle librerie di helper C e GCC standard di impostazione predefinita indipendentemente dalle lingue di input; g ++ selezionerà anche il back-end corretto basato sull'estensione, tranne che penso che compili tutti i sorgenti C come C++ (cioè compila sia .c che .cc come C++) e include libstdC++ nella sua fase di collegamento, indipendentemente dai linguaggi di input. – snr

+1

@snr: OP non riceve un errore del linker, ma un errore del compilatore, dicendo che la funzione non è stata dichiarata. Questo non è causato dall'uso del comando 'gcc' rispetto al comando' g ++ '. A proposito di g ++ come GCC è perfettamente corretto, a proposito. – Kundor

+0

che dire di 'libstdC++'? – snr

5

std :: stoi è un C++11 function. Devi usare lo -std=c++11 per abilitarlo sia in g ++ che in clang ++. Questo è il problema reale, non un errore di collegamento o una definizione specifica del preprocessore.

$ cat test.cxx 
#include <iostream> 
#include <string> 

int main() 
{ 
    std::string test = "45"; 
    int myint = std::stoi(test); 
    std::cout << myint << '\n'; 
} 
$ g++ -otest test.cxx 
test.cxx: In Funktion »int main()«: 
test.cxx:7:17: Fehler: »stoi« ist kein Element von »std« 
    int myint = std::stoi(test); 
       ^
$ g++ -otest test.cxx -std=c++11 
$ ./test 
45 
$ 

modifica: Ho appena visto che hai usato C++ 11. Sei sicuro di averlo fatto nelle tue opzioni di compilazione? Controlla il makefile generato e guarda i comandi eseguiti per essere certi.

Problemi correlati