【问题标题】:How can I use std::begin and std::end without C++11?如何在没有 C++11 的情况下使用 std::begin 和 std::end ?
【发布时间】:2015-12-05 21:55:24
【问题描述】:

我正在尝试编写可以为POJ 编译的代码。 POJ 不使用 C++11,所以我不能使用真正基本的 STL 函数,例如 std::to_stringstd::beginstd::end。我环顾四周,发现another StackOverflow question 在询问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++ 编译没有任何标志等。我该怎么做?

【问题讨论】:

  • 简短的回答是“你不能”。这些是 C++ 11 的特性,你需要 C++ 11 来完成它(或 C++ 14)。你可以像上面的补丁那样实现你自己的 std::begin 等实现。但是你必须用你拥有的任何版本的 C++ 来编写它。
  • @mrunion,为什么这么难过?当然你可以在 C++03 中做 std::begin、std::end 和 std::stoi。
  • 好吧,您无法将它们放入 namespace std 本身,但您可以解决这个问题。
  • 在现代 VS 提供的头文件中查看这些函数的代码,并弄清楚如何对其进行调整。基本上,您需要一个调用 c.begin() 的版本,但需要另一个专门用于数组的版本。

标签: c++ c++11 stl g++ std


【解决方案1】:

非常简单。 例如,这里是 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,当然。加了,急着打字。
  • 还有const_iterator / const C&amp; 过载。数组的另一个重载。
  • 将其命名为 my_begin 有点违背了拥有它的目的
  • 最后的重载不是必须的。对于 const 数组,C 在第三个重载中会被推导出为const,并且比其他两个更特化。
【解决方案2】:

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

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

【讨论】:

  • 重点是它必须使用 vanilla MS-VC++6.0 或 G++ 编译。香草我的意思是没有标志,没有选项,没有额外的。这意味着我不能使用提升。
猜你喜欢
  • 1970-01-01
  • 2012-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-15
  • 2017-11-24
  • 1970-01-01
相关资源
最近更新 更多