【问题标题】:C++ for range loop for template class模板类的 C++ for range 循环
【发布时间】:2021-06-18 08:30:27
【问题描述】:

我在下面有一个模板类,它依赖于两个类 UT 并为这两个类实现了迭代器函数(见本文末尾)。

我可以使用迭代器对类的各个向量进行迭代,
但我想知道是否可以使用 for range 循环语法而不是使用迭代器来做同样的事情。 像

for (auto x : myclass  <double>)
{
  std::cout << x << std::endl ; 
}

我知道它不起作用,但我无法找到语法(如果有的话), 提前感谢您的回答

#include<iostream> 
#include<string> 
#include<vector> 

template<class U,class T>
class MyClass
{
  public:
  MyClass(
    const std::vector<U> & vect_u ,
    const std::vector<T> & vect_t    )
  {
    m_vect_u = vect_u; 
    m_vect_t = vect_t; 
  }

  ~MyClass(){}
  
  // begin()
  template<class Z>
  typename std::enable_if<std::is_same<Z,T>::value, typename std::vector<Z>::iterator>::type
  begin() noexcept { return m_vect_t.begin(); }
  template<class Z>
  typename std::enable_if<std::is_same<Z,U>::value, typename std::vector<Z>::iterator>::type
  begin() noexcept { return m_vect_u.begin(); }
  // end()
  template<class Z>
  typename std::enable_if<std::is_same<Z,T>::value, typename std::vector<Z>::iterator>::type
  end() noexcept { return m_vect_t.end(); }
  template<class Z>
  typename std::enable_if<std::is_same<Z,U>::value, typename std::vector<Z>::iterator>::type
  end() noexcept { return m_vect_u.end(); }
  // cbegin()
  template<class Z>
  typename std::enable_if<std::is_same<Z,T>::value, typename std::vector<Z>::const_iterator>::type
  cbegin() const noexcept { return m_vect_t.cbegin(); }
  template<class Z>
  typename std::enable_if<std::is_same<Z,U>::value, typename std::vector<Z>::const_iterator>::type
  cbegin() const noexcept { return m_vect_u.cbegin(); }
  // cend() 
  template<class Z>
  typename std::enable_if<std::is_same<Z,T>::value, typename std::vector<Z>::const_iterator>::type
  cend() const noexcept { return m_vect_t.cend(); }
  template<class Z>
  typename std::enable_if<std::is_same<Z,U>::value, typename std::vector<Z>::const_iterator>::type
  cend() const noexcept { return m_vect_u.cend(); }

  private: 
    std::vector<U>  m_vect_u ; 
    std::vector<T>  m_vect_t    ; 

}; 


int main()
{ 
  std::vector<double> vect_double = {1.5,2.5,3.5} ; 
  std::vector<int>    vect_int    = {-1,-2,-3} ; 
  MyClass<double,int> myclass( vect_double, vect_int); 
 
  std::cout << "iteration over int" << std::endl ; 
  for(auto itr = myclass.begin<int>(); itr < myclass.end<int>() ; ++itr)
  {
    std::cout << *itr << std::endl ; 
  }

  std::cout << "iteration over double" << std::endl ; 
  for(auto itr = myclass.begin<double>(); itr < myclass.end<double>() ; ++itr)
  {
    std::cout << *itr << std::endl ; 
  }

  return 0 ; 
}

【问题讨论】:

  • 基于范围的 for 循环需要 non-template beginend 成员函数。您提供的是模板。无法调整基于范围的 for 循环来调用 begin&lt;T&gt;()/end&lt;T&gt;() 而不是 begin()/end/()

标签: c++ for-loop c++11 templates


【解决方案1】:

您可以提供返回“范围”的函数(直接std::vector 或包装器):

template <typename Z> // Or SFINAE or if constexpr or any other implementation
auto& getVector() { return std::get<std::vector<Z>&>(std::tie(m_vect_u, m_vect_t)); }

template <typename Z>
const auto& getVector() const { return std::get<const std::vector<Z>&>(std::tie(m_vect_u, m_vect_t)); }

然后

std::cout << "iteration over int" << std::endl ; 
for (auto e : myclass.getVector<int>())
{
    std::cout << e << std::endl ; 
}

Demo

【讨论】:

    【解决方案2】:

    您需要一个具有非模板化beginend 的对象。例如包装MyClass的类模板:

    template <typename Z,typename U,typename T>
    struct MyClassWrapper {
        MyClass<U,T>* parent;
        auto begin() { return parent-> template begin<Z>(); }
        auto end() { return parent-> template end<Z>();}    
    };
    
    template <typename Z,typename U,typename T>
    MyClassWrapper<Z,U,T> make_wrapper(MyClass<U,T>* p){
        return {p};
    }
    

    然后这个工作:

    for (auto& x : make_wrapper<int>(&myclass)){
        std::cout << x << "\n";
    }
    for (auto& x : make_wrapper<double>(&myclass)){
        std::cout << x << "\n";
    }
    

    Live Demo

    【讨论】:

    • 感谢您的解决方案!
    猜你喜欢
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 2012-07-25
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    相关资源
    最近更新 更多