2016-09-29 67 views
6

为什么不能调用STL函数更简短?我一直在寻找在下面的代码片段上cppreference.com为什么C++ STL函数调用需要如此冗长?

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

利用添加可读性:

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

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

+4

为了您的最后两个例子' “你好”'有型'为const char [N]'这意味着它是不可修改。 – NathanOliver

+3

对于初学者来说,你不能只在'char'上使用'std :: toupper',因为它的C过去的东西。 [详细](https://stackoverflow.com/questions/21805674/do-i-need-to-cast-to-unsigned-char-before-calling-toupper)。 –

+2

,同时缩短东西并删除“结束”迭代器等等。对于大多数情况,您可能会减少冗余,但是您“移除”不是这样的情况。 C++可以非常灵活和优雅,因为您为操作提供了开始和结束迭代器。 – Hayt

回答

5

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

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,...

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

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

+1

我明白一般形式的必要性。我有兴趣知道为什么至少没有其他形式。 – Szabolcs

相关问题