Item13 Prefer const_iterators to iterators

   const_iterator 是STL提供的一个等同于const指针的东西,并且它所指向的值是不可变的。标准实践中,当你需要迭代器并且不需要更改迭代器指向的值的时候,你应该使用const_iterator,无论是在C++98,还是C++11,这个标准实践都是正确的,可是在C++98中是并不完全支持const_iterator。什么叫不完全支持呢?

   例如,STL是有const_iterator类型的迭代器,但是没有办法创建一个const_iterator迭代器。容器类型只提供了begin(),end()等返回iterator的成员方法,std::find返回的也是非常量版本的迭代器。或许有人认为可以通过static_cast转化一下,所以有了下面这段代码:

typedef std::vector<int>::iterator IterT;
typedef std::vector<int>::const_iterator ConstIterT;


int main() {
  std::vector<int> values;
  ConstIterT ci = std::find(values.begin(),values.end(),198);
  values.insert(static_cast<IterT>(ci), 198);
  return 0;
}

   上面的代码中std::find返回的是非常量的迭代器,因为后续不会改动,遵从标准实践我通过static_cast将其转化为常量迭代器,而当我在要往这个迭代器出插入一个元素的时候,我又不得不把它转换为非常量的迭代器,因为insert的接受的就是非常量的迭代器,为此我又再次使用了神兵利器static_cast ,可是这次失败了,因为这是一个不可逆的转换,随后我尝试用reinterpret_cast,const_cast都不行。
   不过这一问题在C++11中得以解决,在C++11中可以很轻松的创建和使用常量迭代器,它给容器都提供了cbegincend等成员函数用于返回常量迭代器,修改容器中像insert这种通过传递迭代器来标识位置的成员函数都修改成传递常量迭代器的版本。在C++11中上面的代码可以更改成下面的形式:

int main() {
  std::vector<int> values;
  auto it = std::find(values.cbegin(),values.cend(),198);
  values.insert(it, 198);
  return 0;
}

到此为止可以使用常量迭代器实现标准实践了。

​   虽然C++11提供了返回常量迭代器的成员函数cbegincend,但是这并不通用,因为除了标准容器外,其实还有一些类似于容器的数据结构,这些结构没有beginend等这类方法,为此C++11中提供了非成员函数的版本,可以用于像数组这种类容器的数据结构。只有非成员函数版本的beginend,对于写一些通用代码就更加的方便了。

template <typename C, typename V>
  void findAndInsert(C& container,
                     const V& targetVal,
                     const V& insertVal)
  {
    using std::cbegin;
    using std::end;

    auto it = std::find(cbegin(container), cend(container), targetVal);
    container.insert(it, insertVal);
  }

   上面的代码就比较通用了,对于一切类容器的数据结构都是适用的,而不是只能用于标准的STL容器了。很可惜上面的代码需要C++14的支持,C++11只支持beginend,而到C++14才开始支持cbegincend。如果你的编译器不支持C++14,那么你可以使用下面这段代码代替。

template <typename C>
auto cbegin(const C& container)->decltype(std::begin(container))
{
  return std::begin(container);
}

上面这段代码的实现,巧妙了利用了模版类型推导的原则,具体可以参见Item1

Adding Reversed Numbers

02-28
The Antique Comedians of Malidinesia prefer comedies to tragedies. Unfortunately, most of the ancient plays are tragedies. Therefore the dramatic advisor of ACM has decided to transfigure some tragedies into comedies. Obviously, this work is very hard because the basic sense of the play must be kept intact, although all the things change to their opposites. For example the numbers: if any number appears in the tragedy, it must be converted to its reversed form before being accepted into the comedy play. Reversed number is a number written in arabic numerals but the order of digits is reversed. The first digit becomes last and vice versa. For example, if the main hero had 1245 strawberries in the tragedy, he has 5421 of them now. Note that all the leading zeros are omitted. That means if the number ends with a zero, the zero is lost by reversing (e.g. 1200 gives 21). Also note that the reversed number never has any trailing zeros. ACM needs to calculate with reversed numbers. Your task is to add two reversed numbers and output their reversed sum. Of course, the result is not unique because any particular number is a reversed form of several numbers (e.g. 21 could be 12, 120 or 1200 before reversing). Thus we must assume that no zeros were lost by reversing (e.g. assume that the original number was 12). Input The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. Each case consists of exactly one line with two positive integers separated by space. These are the reversed numbers you are to add. Output For each case, print exactly one line containing only one integer - the reversed sum of two reversed numbers. Omit any leading zeros in the output. Sample Input 3 24 1 4358 754 305 794 Sample Output 34 1998 1
©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值