解释一下代码?

Explain the code?

我看到了这段代码。从输出中我可以推断出余数数组存储数字数组除以 2 的余数。但是我不熟悉语法。

#include <iostream>
#include <functional>
#include <algorithm>

using namespace std;

int main ( )
{

    int numbers[ ] = {1, 2, 3};

    int remainders[3];

    transform ( numbers, numbers + 3, remainders, bind2nd(modulus<int>( ), 2) );

    for (int i = 0; i < 3; i++)
    {
        cout << (remainders[i] == 1 ? "odd" : "even") << "\n";
    }
    return 0;

}

在此上下文中,transform 和 bind2nd 做了什么?我阅读了文档,但我不清楚。

std::bind2nd 来自 C++98/03(特别是 pre-lambdas)。

bin2nd(f, x) 假设 f 是一个函数(或者至少是可以像函数一样调用的东西)并且 x 是一个传递给该函数的值它的第二个参数。它创建了一些类似于函数的东西。当你调用它创建的函数时,相当于调用f(something, x),所以它binds x 到它的输入函数的第二个参数。

如今,您可能会这样写:

transform(std::begin(numbers), std::end(numbers), 
          remainders, 
          [](int x) { return x % 2; });

至于 transform 的作用,它很像一个循环,所以这大致相当于:

for (int i=0; i<3; i++)
    remainders[i] = numbers[i] % 2;

总的来说,我认为原始代码有点不成熟。在我看来,它可能是在所有这些东西都还很新(或者至少对作者来说是新的)的时候写的。如果我要整体完成这项工作,我可能 "collapse" 将这些操作放在一起:

std::transform(std::begin(numbers), std::end(numbers),
            std::ostream_iterator<std::string>(std::cout, "\n"), 
            [](int i) { return std::to_string(i) + (i % 2 == 0 ? " is even" : " is odd"); });

除了在打印结果之前保存一个中间值外,原始数组似乎对 remainders 数组没有任何用处,所以最好不要 create/populate 它。

std::bind2nd is an old function for binding a value to the second parameter of a function. It has been replaced by std::bind 和 lambda。

std::bind2nd returns 一个可调用对象,它接受一个参数并调用包装的可调用对象,该参数作为其第一个参数,绑定参数作为其第二个参数:

int foo(int a, int b)
{
    std::cout << a << ' ' << b;
}

int main()
{
    auto bound = std::bind2nd(foo, 42);
    bound(10); // prints "10 42"
}

std::bind2nd(及其伙伴 std::bind1st)在 C++11 中被弃用并在 C++17 中被移除。它们在 C++11 中被更灵活的 std::bind 以及 lambda 表达式所取代:

int foo(int a, int b)
{
    std::cout << a << ' ' << b;
}

int main()
{
    auto bound = std::bind(foo, std::placeholders::_1, 42);
    bound(10); // prints "10 42", just like the std::bind2nd example above

    auto lambda = [](int a) { foo(a, 42); };
    lambda(10); // prints "10 42", same as the other examples
}

std::transform 对范围的每个元素调用可调用项并将调用结果存储到输出范围中。

int doubleIt(int i)
{
    return i * 2;
}

int main()
{
    int numbers[] = { 1, 2, 3 };
    int doubled[3];

    std::transform(numbers, numbers + 3, doubled, doubleIt);
    // doubled now contains { 2, 4, 6 }
}