如何在不使用C++11的情况下使用std :: begin和std :: end?

3

我正在尝试编写可以在POJ上编译的代码。POJ不使用C++11,因此我不能使用基本的STL函数,如std::to_stringstd::beginstd::end。我四处寻找并找到了另一个StackOverflow问题,询问std::to_string。为了让std::to_string代码能够通过裸的g++ myfile.cpp命令进行编译,有用户建议使用这个补丁,效果很好:

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

我想对std::beginstd::endstd::stoi做同样的事情,但我不确定如何做。我对STL并不熟悉。我只想让我的C++11代码能够在MS-VC++6.0或G++上编译,不需要任何标志等。我该怎么做?

1
简而言之,“你不能这么做”。那些是C++11的特性,你需要使用C++11(或C++14)才能这样做。你可以像上面的补丁那样实现自己的std::begin等函数,但你必须在你所使用的C++版本中编写它们。 - Matt Runion
@mrunion,为什么这么难过?在C++03中当然可以使用std :: begin,std :: end和std :: stoi。 - SergeyA
好吧,你不能直接把它们放在 namespace std 中,但你可以绕过这个问题。 - Neil Kirk
查看现代VS提供的头文件中这些函数的代码,并找出如何进行适应。基本上,您需要一个调用c.begin()的版本,但另一个版本专门针对数组。 - Neil Kirk
2个回答

5
相当简单。例如,这里是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]; } 

1
数组怎么办?这就是为什么需要这些函数的全部原因。 - Neil Kirk
1
还有一个const_iterator/const C&重载。另外还有一个针对数组的重载。 - T.C.
将其命名为my_begin有点违背了它存在的意义。 - imreal
谢谢你给了我一个实现的想法。现在我只需要弄清楚 std::stoi - user3835277
4
最后一个重载不是必要的。对于常量数组,在第三个重载中,C将被推断为const,并且比其他两个重载更为特化。 - dyp
显示剩余3条评论

0

boost::lexical_cast 可以完成与 to_string 相同的工作,而且不需要 C++11。以下是一个简单的示例:

std::string s = boost::lexical_cast<std::string>(12345)

整个意思是这必须使用纯净的 MS-VC++6.0 或 G++ 编译。纯净指的是 没有标记,没有选项,没有额外添加的内容。 这意味着我不能使用 Boost。 - user3835277

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