3

I'm trying to write code that will compile for POJ. POJ doesn't use C++11 so I can't use really basic STL functions like std::to_string, std::begin, or std::end. I looked around and found another StackOverflow question inquiring about std::to_string. To get std::to_string code to compile with a bare g++ myfile.cpp command, a user suggested this patch, which works nicely:

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

I want to do the same thing for std::begin, std::end, and std::stoi, but I'm not sure how to do it. I'm quite unfamiliar with the STL. I just want my working C++11 code to compile with either MS-VC++6.0 or G++ without any flags, etc. How can I do this?

Community
  • 1
  • 1
  • 1
    The short answer is "you can't". Those are C++ 11 features and you need C++ 11 to do it (or C++ 14). You CAN do as the patch above did and implement your own implementation of std::begin, etc. But you have to write it in whatever version of C++ you have. – Matt Runion Sep 09 '15 at 19:44
  • @mrunion, why so sad? Of course you can do std::begin, std::end and std::stoi in C++03. – SergeyA Sep 09 '15 at 19:45
  • Well you wouldn't be able to put them in `namespace std` itself, but you could work around that. – Neil Kirk Sep 09 '15 at 19:47
  • Look in the headers provided by modern VS for the code of these functions and figure out how to adapt it. Basically you need one version which calls `c.begin()` but another version specialized for arrays. – Neil Kirk Sep 09 '15 at 19:48

2 Answers2

5

Pretty straightforward. For instance, here is std::begin:

template <typename C>
typename C::iterator my_begin(C& ctr) { return ctr.begin(); }

template <typename C>
typename C::const_iterator my_begin(const C& ctr) { return ctr.begin(); }

template <typename C, size_t sz>
C* my_begin(C (&ctr)[sz]) { return &ctr[0]; } 

template <typename C, size_t sz>
const C* my_begin(const C (&ctr)[sz]) { return &ctr[0]; } 
dyp
  • 38,334
  • 13
  • 112
  • 177
SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • 1
    What about arrays? That is the whole point why these functions are needed. – Neil Kirk Sep 09 '15 at 19:45
  • @dyp, sure thing. Added it, was typing in a hurry. – SergeyA Sep 09 '15 at 19:45
  • 1
    And a `const_iterator` / `const C&` overload. And another overload for arrays. – T.C. Sep 09 '15 at 19:45
  • Naming it `my_begin` kinda defeats the purpose of having it at all – imreal Sep 09 '15 at 19:50
  • Thanks for giving me an idea of how to do it. Now I just need to figure out `std::stoi`. –  Sep 09 '15 at 19:52
  • @imreal, once you start hacking, nothign stops you from actually naming it begin and putting into std::. Prohibited, but whatever. – SergeyA Sep 09 '15 at 19:53
  • 4
    The last overload isn't necessary. For const arrays, `C` will be deduced to be `const` in the third overload, and it is more specialized than the other two. – dyp Sep 09 '15 at 19:56
  • @gragas: `stoi` is just an `istringstream s(input); s >> i` with some error handling. – Zan Lynx Sep 09 '15 at 19:59
0

boost::lexical_cast can do the same job as that of to_string and it does not require C++11. Below is a simple example:

std::string s = boost::lexical_cast<std::string>(12345)
hungptit
  • 1,414
  • 15
  • 16
  • The whole point is this must compile with vanilla MS-VC++6.0 or G++. By vanilla I mean **no flags, no options, no extras.** This means I cannot use boost. –  Sep 09 '15 at 23:57