【问题标题】:Choosing a for loop based on if condition根据 if 条件选择 for 循环
【发布时间】:2016-08-19 19:37:45
【问题描述】:

基于条件的循环选择。

if(valid)
for (std::multimap<int,int>::reverse_iterator rit=id_count.rbegin(); mcount<10 && rit!=id_count.rend();++rit)
else
for (std::multimap<int,int>::iterator rit=id_match.begin(); mcount<10 && rit!=id_match.end();++rit)

{
    //this is common for both for loop
}

如何在 C++ 中实现这一点?

【问题讨论】:

  • 在循环体内使用通用函数?
  • 如果您可以访问 c++14,请使用 std::for_each,并传递一个通用 lambda。
  • @StoryTeller: std::for_each 附加终止条件?那可能会变得非常丑陋/效率低下
  • @MikeMB,哦,我错过了。而且我不敢相信标准库没有任何带有终止构造的通用访问。好吧,有 std::find_if,但这只是一个 hack。

标签: c++ if-statement for-loop


【解决方案1】:

你别无选择,只能将公共部分放在一个函数中,大致如下:

void somefunction(...)
{
    //this is common for both for loops
}

if (valid)
{
  for (std::multimap<int,int>::reverse_iterator rit=id_count.rbegin(); mcount<10 && rit!=id_count.rend();++rit)
    somefunctiuon(...);
}
else
{
  for (std::multimap<int,int>::iterator rit=id_match.begin(); mcount<10 && rit!=id_match.end();++rit)
    somefunctiuon(...);
}

【讨论】:

    【解决方案2】:

    这可以说是最有用的说明,它值得组合循环逻辑,尽管它确实有效。此处提供利息价值...

    #include <iostream>
    #include <map>
    
    int main()
    {
        std::multimap<int,int> id_count = { {1,2}, {9, -2}, {1,44}, {2,3}, {3,5}, {7,34} };
    
        for (int valid = 0; valid < 2; ++valid)
        {
            std::cout << "valid " << valid << '\n';
            int mcount = 0;
            for (std::multimap<int,int>::iterator it = valid ? id_count.rbegin().base()
                                                             : id_count.begin();
                 mcount<10 && (valid ? it--!=id_count.begin() : it!=id_count.end());
                 (valid ? it : ++it), ++mcount)
            {
                std::cout << "[mcount " << mcount << "] "
                    << it->first << ',' << it->second << '\n';
            }
            std::cout << '\n';
        }
    }
    

    【讨论】:

      【解决方案3】:

      你可以创建一个模板函数:

      #include <map>
      #include <iostream>
      
      template<typename I> void func(I begin, I end) {
          int mcount = 0;
          for (I it = begin; mcount < 10 && it != end; ++it) {
              ++mcount;
              std::cout << "[mcount " << mcount << "] "
                  << it->first << ',' << it->second << '\n';
          }
      }
      
      int main() {
          std::multimap<int,int> id_count = { {1,2}, {9, -2}, {1,44}, {2,3}, {3,5}, {7,34} };
          for (int valid = 0; valid < 2; ++valid) {
              std::cout << "valid " << valid << '\n';
              if (valid) {
                  func(id_count.rbegin(), id_count.rend());
              } else { 
                  func(id_count.begin(), id_count.end());
              }
              std::cout << '\n';
          }
      }
      

      但是恕我直言,这个解决方案有点复杂,所以请考虑其他方式(比如将循环体放在函数中)。

      【讨论】:

        【解决方案4】:

        你可以试试“#if valid”,比如:

        #if 0 for(i=1;i&lt;10;++i) #else for(i=2;i&lt;9;++i) #endif { cout &lt;&lt; i &lt;&lt; endl; }

        【讨论】:

          【解决方案5】:

          在 C++14 中,您还可以选择使用通用 lambda:

          auto common_code = [/* Capture state if needed */] ( auto& Iter )
          {
              // Your common code
          };
          
          if ( valid )
              for ( std::multimap<int, int>::reverse_iterator rit = id_count.rbegin(); mcount < 10 && rit != id_count.rend(); ++rit )
                  common_code( rit );
          else
              for ( std::multimap<int, int>::iterator rit = id_match.begin(); mcount < 10 && rit != id_match.end(); ++rit )
                  common_code( rit );
          

          【讨论】:

            猜你喜欢
            • 2021-02-17
            • 2019-02-23
            • 2022-06-22
            • 2012-08-18
            • 1970-01-01
            • 2015-08-24
            • 2021-12-30
            • 1970-01-01
            相关资源
            最近更新 更多