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

时间:2016-09-29 11:50:24

标签: c++ stl functional-programming

为什么不能更简单地调用STL函数?我正在查看cppreference.com上的以下代码段:

<connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp" keepalive-time="300000"/>.

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

#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;
}

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

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);

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

2 个答案:

答案 0 :(得分:6)

不幸的是,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;

Demo

答案 1 :(得分:2)

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

一般形式才有效。总是!

您可以使用它来就地转换或转换为单独的结果:
std::transform(s.begin(), s.end(), result.begin(),...

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

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

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