2016-09-29 71 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

相關問題