为什么C++STL函数调用需要如此冗长

Why do C++ STL function calls need to be so verbose?

本文关键字:C++STL 函数调用 为什么      更新时间:2023-10-16

为什么对STL函数的调用不能更简短?我在cppreference.com上看到了以下代码片段:

#include <string>
#include <cctype>
#include <algorithm>
#include <iostream>
int main()
{
    std::string s("hello");
    std::transform(s.begin(), s.end(), s.begin(),
                   [](unsigned char c) { return std::toupper(c); });
    std::cout << s;
}

在我看来,应该可以使这次通话更加简短。第一件显而易见的事情是取消lambda:

std::string s("hello");
std::transform(s.begin(), s.end(), s.begin(), std::toupper);
std::cout << s;

但这行不通。由于您通常想要转换整个容器,因此应该可以将其用作参数:

std::string s("hello");
std::transform(s, s.begin(), std::toupper);
std::cout << s;

您也可以省略输出迭代器以按值返回结果:

std::string s("hello");
std::cout << std::transform(s, std::toupper);

在这一点上,临时变量是不必要的:

std::cout << std::transform("hello"s, std::toupper);

增加可读性:

using namespace std;
cout << transform("hello"s, toupper);

这不是更易读、更好看吗?为什么STL函数的设计不允许编写这样简短的代码?在C++标准的未来版本中,是否有可能缩短这些调用?

不幸的是,std::toupper有过载,因此lambda是解决方法。

然后,使用range-v3,您可以将其简化为:

auto to_upper = [](unsigned char c) { return std::toupper(c); }; // To handle overloads
std::cout << std::string("Hello world" | ranges::view::transform(to_upper))
          << std::endl;

演示

std::transform(s.begin(), s.end(), s.begin(),
               [](unsigned char c) { return std::toupper(c); });

一般的形式只是起作用。总是

您可以使用它就地转换或转换为单独的结果:
CCD_ 2。

它可以变换整个容器,也可以只变换一部分。您选择的任何部分:
std::transform(s.begin() + i, s.begin() + j, s.begin() + i,...

它适用于任何序列,即使元素不是容器的一部分。

因此,无论如何都需要通用形式,因为它是最有用的形式。