"To_String" Isn't a Member of "Std"

to_string is not a member of std, says g++ (mingw)

This is a known bug under MinGW. Relevant Bugzilla. In the comments section you can get a patch to make it work with MinGW.

This issue has been fixed in MinGW-w64 distros higher than GCC 4.8.0 provided by the MinGW-w64 project. Despite the name, the project provides toolchains for 32-bit along with 64-bit. The Nuwen MinGW distro also solves this issue.

to_string isn't a member of std?

you may want to specify the C++ version with

g++ -std=c++11 tmp.cpp -o tmp

I don't have gcc 4.8.1 at hand , but in older versions of GCC,
you can use

g++ -std=c++0x tmp.cpp -o tmp

At least gcc 4.9.2 I believe also support part of C++14 by specifying

g++ -std=c++1y tmp.cpp -o tmp

Update:
gcc 5.3.0 (I am using the cygwin version) supports both -std=c++14 and -std=c++17 now.

Why is this program giving an error: to_string is not a member of std. Why?

Those errors could mean:

  1. std::to_string requires header, which you did not include (but it doesn't)
  2. You didn't enable C++11 (I don't know how this works for Visual Studio)
  3. You compiler does not support C++11.

From comments it seems that Visual Studio you are using does not support C++11, so you can use old good string stream and with template you can create an equivalent of std::to_string:

#include <sstream>
#include <string>

template<class T>
std::string toString(const T &value) {
std::ostringstream os;
os << value;
return os.str();
}

//Usage:
std::string valueStr = toString(10);
valueStr.append(toString(1));
valueStr.append(toString(2.5));

Note that to use this function type T needs to have operator<< defined, but it's not a problem with types, which std::to_string supports.

Location of std::to_string function

C++ is not a OO language. You can write OO code in C++, but you can also not.

to_string is not written in an OO style.

There are advantages; the largest one is your code can choose to treat to_string as a customization point by doing

using std::to_string;
std::string foo=to_string(x);

and now any type that implements a to_string in its enclosing namespace works with the above code.

Also, to_string is arguably a method of both source and destination APIs; being a method of either is thus questionable.

Why is std::to_string() not templated?

why C++ decided to disallow people to implement std::to_string for their own type

This is where ADL is useful. We already have the example of how to correctly do this with std::swap, which is successfully done in many codebases already:

template <typename T>
void swap_example(T & a, T & b) {
using std::swap;
swap(a, b);
}

This works if the namespace T is declared in has a compatible swap() function, without needing to overload std::swap. We can do the same thing with std::to_string:

template <typename T>
void to_string_example(T const & x) {
using std::to_string;
to_string(x);
}

This will likewise work if the namespace T is declared in has a to_string function that can accept a T const & argument. For example:

namespace example {
class Foo;

std::string to_string(Foo const &);
}

to_string_example(example::Foo{}) would find and use the corresponding example::to_string function.



remember where to use their version or the std version depends on the types they are dealing with... This sounds like a headache for me.

If this really is such a headache for you, you can hide the ADL behind a utility function in your project:

template <typename T>
std::string adl_to_string(T const & x) {
using std::to_string;
return to_string(x);
}

Now you can use adl_to_string(...) instead of std::to_string(...) everywhere and not have to think about it.

Is specialization of std::to_string for custom types allowed by the C++ standard?

In C++11 and later, is it allowed to specialize std::to_string in the std namespace for custom types?

No. First of all, it is not a template function so you can't specialize it at all.

If you're asking about adding your own overload functions the answer still remains the same.

Documentation snippet from Extending the namespace std:

It is undefined behavior to add declarations or definitions to namespace std or to any namespace nested within std, with a few exceptions noted below

It is allowed to add template specializations for any standard library template to the namespace std only if the declaration depends on a user-defined type and the specialization satisfies all requirements for the original template, except where such specializations are prohibited.


In practice everything will probably work just fine but strictly speaking the standard says there is no guarantee of what will happen.


Edit: I don't have access to the official standard so the following is from the free working draft (N4296):

17.6.4.2 Namespace use

17.6.4.2.1 Namespace std

  1. The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a
    namespace within namespace std unless otherwise specified. A program may add a template specialization
    for any standard library template to namespace std only if the declaration depends on a user-defined type
    and the specialization meets the standard library requirements for the original template and is not explicitly
    prohibited.181
  2. The behavior of a C++ program is undefined if it declares

    2.1 — an explicit specialization of any member function of a standard library class template, or

    2.2 — an explicit specialization of any member function template of a standard library class or class template,
    or

    2.3 — an explicit or partial specialization of any member class template of a standard library class or class
    template.

    A program may explicitly instantiate a template defined in the standard library only if the declaration
    depends on the name of a user-defined type and the instantiation meets the standard library requirements
    for the original template.

  3. A translation unit shall not declare namespace std to be an inline namespace (7.3.1).


Related Topics



Leave a reply



Submit