g++(mingw)报错:“to_string不是std的成员”

271
我正在制作一个小型的词汇记忆程序,其中单词会随机出现以测试我的理解。 我想使用标准C++库,就像Bjarne Stroustroup告诉我们的那样,但是我遇到了一个看似奇怪的问题。
我想将一个长整数转换为std :: string,以便能够将其存储在文件中。 我使用了to_string()来实现此目的。 问题是,当我使用g ++(版本4.7.0,如其--version标志中所述)编译它时,它会显示:
PS C:\Users\Anurag\SkyDrive\College\Programs> g++ -std=c++0x ttd.cpp
ttd.cpp: In function 'int main()':
ttd.cpp:11:2: error: 'to_string' is not a member of 'std'

我的程序出现了这个错误:

#include <string>

int main()
{
    std::to_string(0);
    return 0;
}

但是,我知道这不可能是因为msdn库明确表示它存在,并且Stack Overflow上的早期问题(针对g++版本4.5)说可以通过-std=c++0x标志打开。我做错了什么?

5
可以和我的 GCC 4.4.5 一起工作(即会产生“模糊重载”错误);也许你的 'libstdc++' 已经过时了? - Fred Foo
3
它可以在使用GCC 4.5.1的Ideone上运行,这是链接:http://ideone.com/JNrE1。 - Kerrek SB
5
这对我来说使用g++ 4.6.3有效。你的错误是指第11行。你说你的程序已经"基本被简化为"你的代码,但你发布的代码是否也会出现这个错误? - Vaughn Cato
@VaughnCato - 是的,这就是那个程序。我应该编辑一下,让它更清晰明了。另外,那个多余的 int i 是干嘛的? - Anurag Kalia
2
即使我使用GCC 5.3.1,这对我也不起作用。然而,解决方法很简单,只需使用更高版本的C++标准 - 即通过使用标志-std=c++11或更高版本进行编译。 - Arturo don Juan
可能应该合并类似的问题 - M.M
14个回答

220

这是MinGW下已知的一个bug。相应的Bugzilla链接为Relevant Bugzilla。在评论区中,你可以找到一个补丁使它可以在MinGW下工作。

该问题已在由MinGW-w64项目提供的高于GCC 4.8.0的MinGW-w64发行版中得到修复。尽管名字中带有“64”,但该项目提供了32位和64位的工具链。此外,Nuwen MinGW发行版也解决了这个问题。


2
进一步讨论请参见:https://dev59.com/wmoy5IYBdhLWcg3wcNvh - Ben
12
我使用的是MinGW-w64 4.8.1版本,但它无法工作。我从问题中复制了完全相同的程序,但仍然出现“to_string不是'std'成员”的错误。我编译时使用的命令是:g++ -std=c++0x -o tostring_test.exe tostring_test.cpp。 - zam664
6
我无法解释为什么,但是我通过安装MinGW 4.8.1(具体来说是“x32-4.8.1-posix-dwarf-rev5”版本)**通过MinGW-builds**使std::to_string正常工作。相反,通过“mingw-get”安装或TDM-GCC软件包安装的MinGW 4.8.1则无法使用to_string函数。 - Cerran
5
这段内容的翻译如下:对我而言,这个补丁不够用,我需要在 C:\MinGW\lib\gcc\mingw32\4.8.1\include\c++\mingw32\bits\c++config.h 中像 这里 所描述的那样,定义 #define _GLIBCXX_USE_C99 1 - Zook
3
"MinGW-builds" 是 MinGW-w64 的构建版本,它是一个不同于 MinGW 的项目。MinGW-w64 之所以被分叉出来,其中一个原因就是他们可以修复像本帖讨论的那个 bug。请注意,这里不包括解释或其他非翻译内容。 - M.M
显示剩余7条评论

127
#include <string>
#include <sstream>

namespace patch
{
    template < typename T > std::string to_string( const T& n )
    {
        std::ostringstream stm ;
        stm << n ;
        return stm.str() ;
    }
}

#include <iostream>

int main()
{
    std::cout << patch::to_string(1234) << '\n' << patch::to_string(1234.56) << '\n' ;
}

请不要忘记包含#include <sstream>

有没有办法也包含 stod 函数? - Jackie
2
请注意,这并不是关于尾随零的精确解决方案。原始的 std::to_string(0.75) 通常会返回 "0.750000"(默认的 sprintf %d 格式),而这将返回 "0.75"。请参见此处的原因:https://dev59.com/YWYr5IYBdhLWcg3wb5rc#13686914 - Krzysztof Bociurko

49

正如建议的那样,这可能是您编译器版本的问题。

尝试使用以下代码将long转换为std::string

#include <sstream>
#include <string>
#include <iostream>

int main() {
    std::ostringstream ss;
    long num = 123456;
    ss << num;
    std::cout << ss.str() << std::endl;
}

我还没有运行它,但感谢您解决了我的紧急困境。现在我只需要弄清楚它是如何工作的。 :) - Anurag Kalia
请注意,如果您想要一个 std::string,则应使用 .str() - Christian Mann
1
请注意,这并不是关于尾随零的精确解决方案。原始的 std::to_string(0.75) 通常会返回 "0.750000"(默认的 sprintf %d 格式),而这将返回 "0.75"。请参见此处的原因:https://dev59.com/YWYr5IYBdhLWcg3wb5rc#13686914 - Krzysztof Bociurko

20
请使用此函数...
    #include<sstream>
    template <typename T>
    std::string to_string(T value)
    {
      //create an output string stream
      std::ostringstream os ;

      //throw the value into the string stream
      os << value ;

      //convert the string stream into a string and return
      return os.str() ;
    }

    //you can also do this
    //std::string output;
    //os >> output;  //throw whats in the string stream into the string

2
请在您的答案中添加一些解释(至少注释),无论代码有多容易理解。请注意,这是一种指示,而不是代码本身。 - vefthym
5
有临时的解决办法固然好,但我认为通常最好找出标准解决方案无法编译的原因,而不是匆忙拼凑一些东西。 - Matt Coubrough
1
“标准”方法(std::to_string)通常有效,但有时会失效。 sstream是“标准”的解决方法。 - Nick Vence
请注意,这并不是关于尾随零的精确解决方案。原始的 std::to_string(0.75) 通常会返回 "0.750000"(默认 sprintf %d 格式),而这将返回 "0.75"。查看此处以了解原因:https://dev59.com/YWYr5IYBdhLWcg3wb5rc#13686914 - Krzysztof Bociurko

12

to_string是Cygwin的一个当前问题

这里有一个对旧帖子的新回答。虽然有一个新的帖子出现了,但很快就被压制了, Cygwin: g++ 5.2: ‘to_string’ is not a member of ‘std’

太糟糕了,也许我们会得到一个更新的答案。根据@Alex的说法,截至2015年11月3日,Cygwin g++ 5.2仍然无法正常工作。

2015年1月16日,Red Hat的Cygwin维护者Corinna Vinschen 表示问题 是newlib的一个缺陷。它不支持大多数long double函数,因此不符合C99标准。

Red Hat仍然希望在某个时候将“long double”功能纳入newlib中。

2015年10月25日科琳(Corrine)也说道,

如果有一些数学知识的人能够为newlib贡献缺失的long double函数,那就太好了。

所以这就是我们目前的情况。也许我们中有一个拥有这方面知识和时间的人可以做出贡献并成为英雄。

Newlib在这里


看到他们直到今年才从通过邮件发送补丁迁移到Git,感觉有些泄气... - rr-

8

更改默认的C++标准

(编译文件失败)错误:'to_string'不是'std'的成员

-std=c++98

(编译文件成功)

-std=c++11或-std=c++14

在Cygwin G++(GCC)5.4.0上测试通过


3
如果我们使用一个类似于上面所示的模板轻量级解决方案,如下所示:
namespace std {
    template<typename T>
    std::string to_string(const T &n) {
        std::ostringstream s;
        s << n;
        return s.str();
    }
}

很遗憾,在某些情况下我们会遇到问题。例如,对于static const成员:

hpp

class A
{
public:

    static const std::size_t x = 10;

    A();
};

C++

A::A()
{
    std::cout << std::to_string(x);
}

并且链接:

CMakeFiles/untitled2.dir/a.cpp.o:a.cpp:(.rdata$.refptr._ZN1A1xE[.refptr._ZN1A1xE]+0x0): undefined reference to `A::x'
collect2: error: ld returned 1 exit status

这里有一种解决问题的方法(将类型添加到size_t):
namespace std {
    std::string to_string(size_t n) {
        std::ostringstream s;
        s << n;
        return s.str();
    }
}

祝好运。


3

如果c++版本较低,to_string()函数是无法使用的。可以使用替代方法,例如sprintfostringstream


2
事实上,libstdc++自4.8.0版本起就支持在*-w64-mingw32目标中使用std::to_string。然而,这并不包括对MinGW.org、Cygwin和变体(例如来自MSYS2的*-pc-msys)的支持。请参见https://cygwin.com/ml/cygwin/2015-01/msg00245.html
我在MinGW-w64的bug得到解决之前,已经实现了一个解决方法。与其他答案中的代码不同,这是对libstdc++的模拟(尽可能地)。它不需要字符串流构造,但依赖于libstdc++扩展。即使我现在在Windows上使用mingw-w64目标,它仍然适用于多个其他目标(只要不使用long double函数)。

2

如果有人想知道为什么在Android上会出现这种情况,可能是因为您正在使用错误的C++标准库。请尝试将build.gradle中的C++库从gnustl_static更改为c++_static,并将CMakeLists.txt中的C++标准从-std=gnu++11更改为-std=c++11


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接