to_string is not a member of std
现象
cocos2d-x 2.2.6 项目的源码中使用了 std::to_string()
方法,使用 NDK r9d 编译的时候,报如下错误:
1error: 'to_string' is not a member of 'std'
Application.mk 文件的部分内容如下:
1APP_STL := gnustl_static
2NDK_TOOLCHAIN_VERSION := 4.8
3APP_CPPFLAGS := -frtti -std=c++11 -fexceptions -Wno-error=format-security -Wno-literal-suffix -Wno-deprecated-declarations -fsigned-char -Os $(CPPFLAGS)
换用 NDK 10e ,错误依然。
快速解决
想快速解决这个问题,可以自己写一个 std::to_string()
替换标准库中的。
首先写一个 stdtostring.h
文件:
1#ifndef STDTOSTRING_H
2#define STDTOSTRING_H
3#include <string>
4#include <sstream>
5
6using namespace std;
7namespace std
8{
9 template < typename T > std::string to_string( const T& n )
10 {
11 std::ostringstream stm ;
12 stm << n ;
13 return stm.str() ;
14 }
15}
16#endif
然后在需要使用 std::to_stirng()
方法的源文件中包含它:
1#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
2#include "stdtostring.h"
3#endif
追根溯源
Why gnustl_static 中介绍了采用 c++_static
和 clang
编译器来实现 std::to_string()
支持,于是我尝试了下:
1# APP_STL := gnustl_static
2# NDK_TOOLCHAIN_VERSION := 4.8
3APP_STL := c++_static
4NDK_TOOLCHAIN_VERSION := clang
根据 C++ Library Support 的说明,c++_static
对应的是 The LLVM libc++ runtime (static) ,因此应该采用 clang 的工具链进行编译。
结果是: std::to_string()
编译正常,但出现下面的错误:
1In file included from src/Utilities.cpp:1:0:
2android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1498:46: error: expected unqualified-id before 'float'
3inline _LIBCPP_INLINE_VISIBILITY float remainder(float __x, float __y) _NOEXCEPT {return remainderf(__x, __y);}
4 ^
5android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1498:46: error: expected ')' before 'float'
6android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1499:46: error: expected unqualified-id before 'long'
7inline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __x, long double __y) _NOEXCEPT {return remainderl(__x, __y);}
8 ^
9android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1499:46: error: expected ')' before 'long'
10android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1509:1: error: expected ')' before '__x'
11remainder(_A1 __x, _A2 __y) _NOEXCEPT
12^
13android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1559:46: error: expected unqualified-id before 'float'
14inline _LIBCPP_INLINE_VISIBILITY float round(float __x) _NOEXCEPT {return roundf(__x);}
15 ^
16android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1559:46: error: expected ')' before 'float'
17android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1560:46: error: expected unqualified-id before 'long'
18inline _LIBCPP_INLINE_VISIBILITY long double round(long double __x) _NOEXCEPT {return roundl(__x);}
19 ^
20android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1560:46: error: expected ')' before 'long'
21android-ndk-r9d/sources/cxx-stl/llvm-libc++/libcxx/include/cmath:1565:1: error: expected ')' before '__x'
22round(_A1 __x) _NOEXCEPT {return round((double)__x);}
minggo 在 Cocos can't compile Android with APP_STL := c++_static 中提到:
A prebuilt version can only support one type of c++ lib. Did you mean we should provide two kinds of prebuilt libcocos2d that using two different c++ libs?
I don't know if cocos2d can compile with c++_static or not. I don't remember if there is a good reason to choose one instead of other one. But cocos2d-x uses gnustl_static from very early version, so we know it works well. You can replace it with c++_static if you like, but it is not fully tested.
因此我怀疑在 cocos2d-x 的旧版本中,c++_static
是没有经过完整测试的。
也有人说 在新版本(>3.7)中, gnustl_static
会导致 lambda 和 std::to_string
不能使用,已经切换到使用 c++_static
和 clange 组合。
I never made it to work with gnustl_static and gcc with all the c++11 features. I was getting crashes in simple lambdas, as mentioned std::to_string was missing and much more, so i've switched to c++_static and clang long time ago.
既然目前我们依然在使用旧版本,就不折腾了。
- 文章ID:2451
- 原文作者:zrong
- 原文链接:https://blog.zengrong.net/post/std-to-string-in-ndk/
- 版权声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,非商业转载请注明出处(原文作者,原文链接),商业转载请联系作者获得授权。