如何在不提升的情况下将 C++11 代码转换为 C++98

How can I convert the C++11 code to C++98 without boost?

本文关键字:C++11 代码 转换 C++98 情况下      更新时间:2023-10-16

>我有以下函数:

template<typename containerT>
void incElement(containerT c){
  for(auto i = c.begin(); i != c.end(); ++i) {
    for(auto j = (*i).begin(); j != (*i).end(); ++j) {
      ++(*j);
    }
  }
}

如何使用 C++98 完成此操作?我试过了:

template<typename containerT, typename containerRowT, typename containerElementT>
void incElement(containerT<containerRowT<containerElementT> > c) {
  for(containerT<containerRowT<containerElementT> >::iterator i = c.begin(); i != c.end; ++i) {
    for(containerRowT<containerElementT> >::iterator j = (*i).begin(); j != (*j).end(); ++j){
      ++(*j);
    }
  }
}

它不起作用并给我错误,例如:

test.cpp:4:17: error: ‘containerT’ is not a template
 void incElement(containerT<containerRowT<containerElementT> > c) {
                 ^
test.cpp:4:28: error: ‘containerRowT’ is not a template
 void incElement(containerT<containerRowT<containerElementT> > c) {
                            ^
test.cpp: In function ‘void incElement(containerT)’:
test.cpp:5:7: error: ‘containerT’ is not a template

等。

我该怎么做?

您始终可以将auto替换为模板,因为它们遵循相同的类型扣除规则:

template<typename Iterator>
void inner(Iterator begin, Iterator end)
{
    for (; begin != end; ++begin)
    {
        ++*begin;
    }
}
template<typename Iterator>
void outer(Iterator begin, Iterator end)
{
    for (; begin != end; ++begin)
    {
        inner(begin->begin(), begin->end());
    }
}
template<typename Container>
void incElement(Container& container)
{
    outer(container.begin(), container.end());
}

请注意,我更改了incElement的签名以通过引用接受其参数。否则,将修改容器的副本,并且客户端将无法观察到任何更改。

假设使用的容器遵循正常的std约定,您可以显式拼写出类型:

template <typename containerT>
void incElement(containerT &c)  //assuming you want a reference here, otherwise you'll be mnodifying a local copy only
{
  typedef typename containerT::iterator TypeOfI;
  typedef typename containerT::value_type TypeOfStarI;
  typedef typename TypeOfStarI::iterator TypeOfJ;
  for (TypeOfI i = c.begin(); i != c.end(); ++i) {
    for (TypeOfJ j = i->begin(); j != i->end(); ++j) {
      ++*j;
    }
  }
}

在函数的第一个版本中,containerT不是模板。它是一个类(它可以是模板的实例化,但这无关紧要)。

如果containerT满足标准容器概念,那么你可以写:

for (typename containerT::iterator i ...) {
    for (typename containerT::value_type::iterator j ...)

编译器会告诉你问题出在哪里。您正在将containerT声明为类型,但您将其用作模板。因此,您可以尝试将containerT更改为模板模板参数(与containerRow相同)。

template<template<class> class containerT, template<class> class containerRowT, typename containerElementT>
void incElement(containerT<containerRowT<containerElementT> > c);

那么对于 STL 容器来说呢:

template<typename containerT>
void incElement(containerT c){
  for(typename containerT::iterator i = c.begin(); i != c.end(); ++i) {
    for(typename containerT::value_type::iterator j = (*i).begin(); j != (*i).end(); ++j) {
       ++(*j);
    }
  }
}