【问题标题】:How to create my own loop version in C++?如何在 C++ 中创建我自己的循环版本?
【发布时间】:2023-03-19 09:07:01
【问题描述】:

我想知道是否可以创建自定义函数,例如 forfor_eachwhile 等。

没有什么我想做的,现有的循环不会做。我只是想了解它们是如何工作的,以及是否需要创建自己的。

例如,如果想创建一个只接受参数的 for 函数的另一个版本。

在这个例子中,我想创建一个只接受一个参数的 for,一个整数。 而不是写

for (int i = 0; i < 50; ++i)

我会创建一个这样的版本

for_(50)

他们会采取同样的行动。我该怎么做?

这个问题我已经发到another forum了。

【问题讨论】:

  • forwhile 不是函数,它们是内置于语言本身的语句。您可以自己实现std::for_each 或使用其中一个循环语句的其他函数。
  • 您不能创建新的语言关键字(或修改现有的),但您可以创建任何您喜欢的自定义功能
  • 在您的自定义函数中使用汇编代码。

标签: c++


【解决方案1】:

除了其他答案中的建议之外,您还可以创建一个如下所示的函数,但最后它与使用标准 std::for_each 非常相似。

#include <iostream>
#include <functional>

template<typename C, typename F>
void for_(C begin_, C end_, F&& f) { // [begin_, end_)
    for (C i =  begin_; i < end_; ++i) {
        f(i);
    }
}

template<typename C, typename F>
void for_(C count, F&& f) { // special case for [0, count)
    for_(0, count, f);
}

void mul2(int x) {
    std::cout << x*2 << " ";
}

int main() {
    for_(10, [](int i) { std::cout << i << "\n"; });
    for_(2, 10, mul2);
}

【讨论】:

  • 知道我不能完全按照我的意愿去做很糟糕,但我很欣赏这段代码,它非常有用。但是,有没有办法让它在调用它的行中不那么冗长??
  • @HBatalha AFAIK 绕过 C++ 语法的唯一方法是通过宏,但正如在其他答案中评论的那样,这是一个丑陋且不推荐的解决方案,因为缺点会压倒好处。
【解决方案2】:

一个丑陋且不安全的解决方案是使用宏:

#define REPEAT(i,N) for(int (i) = 0; (i) < (N); ++(i))

int main()
{
  REPEAT(i,10) std::cout << i << std::endl;

  return 0;
}

【讨论】:

  • 为什么不使用模板函数呢?
  • @JesperJuhl 我不确定我们是否可以用模板模仿for(...) statement 的语法。你有这个方向的想法吗?
  • 老实说,通过保持宏的标准样式可以使这变得不那么难看。例如,称之为 REPEAT。这使它很明显并且很好地表达。没什么好害怕的。
  • @AlexGeorg 是的,我同意,我根据你的评论修正了我的答案
  • 这个最接近我的意图,奇怪,因为它使用宏。但是为什么所有的括号??
【解决方案3】:

您不能为新循环扩展 C++ 语法。

您可以使用宏,但这非常难看,通常最好避免。获得类似结果的另一种方法是将仿函数作为参数传递,这在将 lambda 表达式引入 C++ 时得到了很大帮助。您可以在 &lt;algorithm&gt; 标头中找到一些此类示例。

例如:

#include <algorithm>
#include <vector>
int main()
{
    std::vector<int> numbers = { 1, 4, 5, 7, 10 };
    int even_count = 0;
    for (auto x : numbers)
    {
        if (x % 2 == 0)
        {
            ++even_count;
        }
    }
    auto even_count2 = std::count_if(numbers.begin(), numbers.end(), [](int x) { return x % 2 == 0; });
}

【讨论】:

    【解决方案4】:

    您可以使用 lambda 函数并将函数对象作为参数传递给循环的每次迭代。

    #include <iostream>
    #include <functional>
    
    int main()
    {
        auto for_ = [](int start, int size, std::function<void (int i)> fn)
        {
            int end = start + size;
    
            for (int i = start; i < end; ++i)
            {
                fn(i);
            }
        };
    
        for_(0, 10, [](int i) { std::cout << i << std::endl; });
        for_(0, 10, [](int i) { std::cout << i*2 << std::endl; });
    }
    

    您似乎在重新发明轮子。你可以使用std::for_each

    但是,您可以使用自定义 lambda 函数来执行不同的操作,并且只需在 lambda 本身内实现操作,而无需为操作获取函数对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-13
      • 2010-10-12
      • 2013-09-22
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      相关资源
      最近更新 更多