Compile error: 'stoi' is not a member of 'std'
我的代码:
1 2 3 4 5 6 7 8 9 10
| #include <iostream>
#include <string>
int main()
{
std::string test ="45";
int myint = std::stoi(test);
std::cout << myint << '
';
} |
给我编译错误:
1 2 3
| error: 'stoi' is not a member of 'std'
int myint = std::stoi(test);
^ |
但是,据此,此代码应可以正常编译。 我在我的CMakeLists.txt文件中使用行set(CMAKE_CXX_FLAGS"-std=c++11 -O3")。
为什么不编译?
更新:我正在使用gcc,并且运行gcc --version会打印出:
1
| gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010 |
-
您没有指定要使用的编译器版本。
-
查看此线程cplusplus.com/forum/beginner/120836
-
@CaptainObvlious,我正在使用gcc版本5.2.1
-
在Fedora 24上编译gcc 6.1.1时没有问题。
-
无法在Ubuntu上使用g ++ 5.2.1进行复制
-
@Karnivaurus首先,gcc是C编译器,而不是C ++编译器。 g++是C ++编译器,因此应确保使用正确的编译器进行编译。
-
@ DOUGLASO.MOEN真的吗? 这似乎不适用于StackedCrooked。
-
@VermillionAzure:gcc将根据文件扩展名很好地编译C ++,但是它并不需要链接标准库,而g++包装器可以这样做。
-
另外,我也不知道编译器版本是否有问题:使用Godbolt在5.2.0上可以正确编译
-
@Kundor Ah,谢谢。
-
VTC。 问题无法重现,我很难相信我们在这里有完整的细节。
在libstdc ++中,stoi,stol等的定义以及to_string函数受以下条件的保护:
1 2
| #if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) |
我以前在一个平台(即android上的Termux)上遇到过这种故障,导致即使x ++ 6.1和C ++ 14标准也无法使用to_string。在那种情况下,我只是做了
1
| #define _GLIBCXX_USE_C99 1 |
在包含任何东西之前,这些功能突然存在。 (您应该将其放在第一个,甚至放在命令行上,而不是放在包含之前,因为另一个标头可能首先包含,然后其包含保护措施将使它无法看到您的宏。)
我没有调查为什么没有首先设置此宏。显然,如果您想让代码真正起作用,这是一个令人担忧的问题(在我的情况下,我并不是特别注意,但是FWIW没问题。)
您应该检查是否未定义_GLIBCXX_USE_C99或_GLIBCXX_HAVE_BROKEN_VSWPRINTF(在MinGW上可能是这种情况?)
-
libstdc ++ umm OP问题当然与gcc有关。他必须使用g++。因为Rup(一个SO用户)说gcc将基于文件扩展名选择正确的后端编译器(即,将.c编译为C,将.cc编译为C ++),并且仅通过标准C和GCC帮助器库链接二进制文件默认值,与输入语言无关; g ++还将根据扩展名选择正确的后端,除了我认为它会将所有C源代码编译为C ++(即它将C和.cc都编译为C ++),并且在链接步骤中将libstdc ++包括在内,而不管输入语言是什么。
-
@snr:OP没有收到链接器错误,但是是编译器错误,表示未声明该函数。这不是由gcc命令与g++命令引起的。顺便说一句,将g ++称为GCC是完全正确的。
-
libstdc++呢?
-
这不是一种联系吗?
-
@snr:是的,需要将其链接。如果未正确链接,则std中的任何内容均不起作用。它不会因缺少一个特定功能而反映出来,可以通过使用std::atoi进行"修复"。另外,OP出现编译器错误:这与链接没有任何关系。这意味着即使应该,编译器也不会在包含的标头中看到所需的定义。链接最后发生:如果未链接libstdc ++的必要部分,则会导致许多未定义的引用,而不是编译器错误。
-
不要手动设置这些定义。 使用正确的编译器标志。 问题是C ++标准(__cplusplus >= 201103L)。 您应该确保使用std=c++11进行编译。 您应该使用正确的C ++版本,而不是设置_GLIBCXX_USE_C99(它设置C标准版本以引入这些符号)。 OP提到他们已经设置了set(CMAKE_CXX_FLAGS"-std=c++11 -O3"),这意味着唯一可能的问题是这些标志实际上并未将其放入编译器命令,或者稍后在命令行上将std重置为其他命令。
std :: stoi是C ++ 11函数。您必须使用-std=c++11在g ++和clang ++中都启用它。这是实际问题,而不是链接错误或特定的预处理程序定义。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| $ cat test.cxx
#include <iostream>
#include <string>
int main()
{
std::string test ="45";
int myint = std::stoi(test);
std::cout << myint << '
';
}
$ 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
$ |
编辑:我刚刚看到您使用c ++ 11。您确定会将其纳入您的编译选项吗?检查生成的makefile,并观察执行的命令是否
-
不,这确实取决于平台(我的平台是MIPS的OpenWRT)。 Kundor对_GLIBCXX_USE_C99提出了重要的建议。
您的版本似乎是最新的,因此应该没有问题。我认为可能与gcc有关。尝试使用g++。(很可能会自动链接问题。如果仅在C ++文件上运行gcc,它将不会像g ++那样"正常工作"。这是因为它不会自动链接到C ++ std库等。 )。我的第二个建议是尝试std::atoi。
@我已解决此问题。 std::stoi使用libstdc ++。关于GNU标准C ++库。在gcc中,您必须链接添加-lstdc++。但是,在g ++中,libstdc ++是自动链接的。
使用gcc和使用g ++
注意它是如何编译的
使用g ++:g++ -std=c++11 -O3 -Wall -pedantic main.cpp && ./a.out
使用gcc:gcc -std=c++11 -O3 -Wall -pedantic -lstdc++ main.cpp && ./a.out
我认为您应该将标志设置为set(CMAKE_EXE_LINKER_FLAGS"-libgcc -lstdc++")(未经测试)
1 2 3
| #include <cstdlib>
int myInt = std::atoi(test.c_str()); |
-
谢谢-使用std::atoi对我有用。尽管我仍然不确定std::stoi的根本问题...
-
@Karnivaurus问题与C ++标准库中的链接有关。使用gcc命令,您必须手动使用-lstdc++之类的命令进行操作,但是g++将自动为您链接。例
-
@Vermilion:如果它与atoi一起正常工作,则不是链接错误。正如错误首先指出的那样,它的功能未在标头中声明,因为它们已被预处理器删除。这与链接或gcc与g++命令无关。
-
我真的很想看到某人的信息不完整或不正确。仔细检查链接:gcc和g ++ @Kundor
-
@snr:是的,这完美地说明了我在上面给出的所有解释您的解释不正确的原因。就像我说的那样:对于gcc,没有任何效果:并非只有一个函数stoi会出现问题,将其更改为atoi会使它神奇地起作用。什么也没做。并且,所有错误均为链接器错误。没有一个编译器错误,因为编译器对链接一无所知。当编译器说找不到任何东西时,这意味着它没有输入到编译器中。这不是相同的,因为链接器找不到参考。
-
即使使用atoi解决了OP问题,这也是错误的答案。
-
好的,如果问题与链接无关,那么请解释您的投票和@SergeyA的原因
-
@snr,已经被多次解释-OP存在编译问题,而不是链接问题。链接问题不会由std::atoi修复。
-
我说过它与gcc和g ++有关。因此,它暗含关于链接的信息。 gcc和g ++ @SergeyA
-
@snr,不,这与链接无关,这就是为什么您的答案不正确的原因。您自己的链接显示-错误不相同,并且atoi无法修复它。
-
@snr这显然与链接无关,因为那是编译器错误。这是一个错误的答案。如果与链接有关,则可以使用-c标志,但您不会看到它。
如果使用Cmake进行编译,请添加以下行:
" add_definitions(-std = c ++ 11)"
在find_package命令之后。