简体   繁体   English

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

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

I have the function: 我有这个功能:

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);
    }
  }
}

How can I make this work with C++98? 如何使用C ++ 98实现这一功能? I tried: 我试过了:

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);
    }
  }
}

And it does not work and gives me error like: 它不起作用,并给我错误,如:

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

etc. 等等

How can I do this? 我怎样才能做到这一点?

You can always replace auto by templates, because they follow the same type deduction rules: 您始终可以使用模板替换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());
}

Note that I changed the signature of incElement to accept its argument by reference. 请注意,我更改了incElement的签名以通过引用接受其参数。 Otherwise, a copy of the container would be modified, and the client would not be able to observe any changes. 否则,将修改容器的副本,并且客户端将无法观察到任何更改。

Assuming the containers used follow normal std conventions, you can spell out the types explicitly: 假设使用的容器遵循正常的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;
    }
  }
}

In the first version of your function, containerT is not a template. 在函数的第一个版本中, containerT不是模板。 It is a class (and it can be an instantiation of a template, but that's irrelevant). 它是一个类(它可以是模板的实例化,但这是无关紧要的)。

If containerT satisfies the standard Container concept then you would write: 如果containerT满足标准的Container概念,那么你会写:

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

Well compiler tells you where the problem is. 编译器会告诉您问题所在。 You are declaring containerT as a type, but you are using it as a template. 您将containerT声明为类型,但您将其用作模板。 So you can try to change containerT to template template argument (same for containerRow ). 因此,您可以尝试将containerT更改为模板模板参数(对于containerRow )。

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

And what about this for STL containers: 那对于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);
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM