49

I'm using android NDK r9d and toolchain 4.8 but I'm not able to use std::to_string function, compiler throws this error:

 error: 'to_string' is not a member of 'std'

Is this function not supported on android ndk? I try APP_CPPFLAGS := -std=c++11 with no luck.

6 Answers 6

62

You can try LOCAL_CFLAGS := -std=c++11, but note that not all C++11 APIs are available with the NDK's gnustl. Full C++14 support is available with libc++ (APP_STL := c++_shared).

The alternative is to implement it yourself.

#include <string>
#include <sstream>

template <typename T>
std::string to_string(T value)
{
    std::ostringstream os ;
    os << value ;
    return os.str() ;
}

int main()
{
    std::string perfect = to_string(5) ;
}
7
  • 3
    I make some tries with no luck (LOCAL_CPPFLAGS += -std=c++11, LOCAL_CPPFLAGS += -std=gnu+11 etc.), and also I found some answers (stackoverflow.com/questions/17950814/…) which explains that ndk not supports new c++11 string function, so finally I implement to_string method as you suggests. Thanks :).
    – albciff
    Commented Apr 1, 2014 at 22:16
  • I have tried it but gives error on std::ostringstream. The issue might be about Android Studio 2.2 alpha 6. Is there any easy way to convert?
    – Onur Tuna
    Commented Jul 27, 2016 at 11:22
  • Extremely helpful all for compilers that don't support C++11. BTW: Is there a way (a macro definition) to check if C++11 is present, to skip this?
    – Wolf
    Commented Sep 20, 2017 at 9:56
  • I just found the char template specializations missing, you need 3 of them, for: char, signed char, unsigned char
    – Wolf
    Commented Sep 20, 2017 at 13:27
  • I have used the same function but application get crash for some devices with below log libloglib-jni.so 0xdd7bdacf std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_ostringstream() (basic_ios.h:276) 36 libart.so 0xf4832812 (Missing) 37 libloglib-jni.so 0xdd7a5851 std::string patch::to_string<int>(int const&) can you please provide any solution if you have. Commented Nov 30, 2017 at 12:09
26

With NDK r9+ you can use llvm-libc++ which offers full support for cpp11.

In your Application.mk you have to add:

APP_STL:=c++_static 

or

APP_STL:=c++_shared
7
  • 2
    using cocos2d-x this worked to get around the std::to_string compile issue. However it caused other build problems down stream: "error: 'pthread_key_t' does not name a type static pthread_key_t s_threadKey" In case some tries this. I was never able to solve that. As mentioned here stackoverflow.com/questions/22164564/… changing compilers led to other compile issues... The accepted answer got around the issue in the short term... Commented Feb 23, 2015 at 21:44
  • 1
    @Hunter I didn't mention that on my question however I was using cocos2d, and the accepted answer is simply an clean and as you said got around the issue so this is why I did accept it :)
    – albciff
    Commented Feb 26, 2015 at 17:58
  • Yes I too went with the accepted answer, I was not able to figure out exactly how to use this approach correctly. I was missing other threading libs. Probably could have done it if I spent more time... I just wanted that specific error here so if I ever run into this again I will have a hit right away :) Commented Feb 27, 2015 at 2:21
  • I was looking for this one for hours, so thank you thursdaysDove!
    – Kyone
    Commented Jun 17, 2015 at 18:20
  • I also get other errors down stream with this answer.
    – Jonny
    Commented Jul 16, 2015 at 1:15
13

Gradle

If you looking for solution for Gradle build system. Look at this answer.

Short answer.

Add the string

arguments "-DANDROID_STL=c++_shared"

in your build.gradle. Like

android {
  ...
  defaultConfig {
    ...
    externalNativeBuild {
      cmake {
        ...
        arguments "-DANDROID_STL=c++_shared"
      }
    }
  }
  ...
}
1
  • 1
    Actually this is the only valid answer ,given that today's native development for Android is mostly done with Android Studio which uses Gradle.
    – Michael IV
    Commented Apr 9, 2018 at 14:42
1

Experimental Gradle Plugin

If you're looking for a solution for the Experimental Gradle plugin, this worked for me...

Tested with com.android.tools.build:gradle-experimental:0.9.1

model {
  ...
  android {
    ...
    ndk {
      ...
      stl = "c++_shared"
    }
  }
}
0

I could not use c++_static, it gave some errors about undefined exceptions. So I returned to the gnustl_static.

But in NDK sources, in sources/cxx-stl/llvm-libc++/src/string.cpp, I found implementation of to_string(int) and tried to copy it to my code. After some corrections it worked.

So the final piece of code I had:

#include <string>
#include <algorithm>

using namespace std;


template<typename S, typename P, typename V >
inline
S
as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
{
    typedef typename S::size_type size_type;
    size_type available = s.size();
    while (true)
    {
        int status = sprintf_like(&s[0], available + 1, fmt, a);
        if ( status >= 0 )
        {
            size_type used = static_cast<size_type>(status);
            if ( used <= available )
            {
                s.resize( used );
                break;
            }
            available = used; // Assume this is advice of how much space we need.
        }
        else
            available = available * 2 + 1;
        s.resize(available);
    }
    return s;
}

template <class S, class V, bool = is_floating_point<V>::value>
struct initial_string;

template <class V, bool b>
struct initial_string<string, V, b>
{
    string
    operator()() const
    {
        string s;
        s.resize(s.capacity());
        return s;
    }
};

template <class V>
struct initial_string<wstring, V, false>
{
    wstring
    operator()() const
    {
        const size_t n = (numeric_limits<unsigned long long>::digits / 3)
          + ((numeric_limits<unsigned long long>::digits % 3) != 0)
          + 1;
        wstring s(n, wchar_t());
        s.resize(s.capacity());
        return s;
    }
};

template <class V>
struct initial_string<wstring, V, true>
{
    wstring
    operator()() const
    {
        wstring s(20, wchar_t());
        s.resize(s.capacity());
        return s;
    }
};

string to_string(int val)
{
    return as_string(snprintf, initial_string<string, int>()(), "%d", val);
}
0

For Android Studio, add this in build.gradle (Mobile App)

externalNativeBuild {
    cmake {
        cppFlags "-std=c++11"

        arguments "-DANDROID_STL=c++_static"
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.