簡體   English   中英

為什么 C++20 范圍不只提供管道語法?

[英]Why do C++20 ranges not provide only pipe syntax?

我知道這個問題聽起來很奇怪,所以這里有一些上下文。

最近我很失望地得知 C++20 范圍內的 map reduce 並沒有像人們期望的那樣工作,即

const double val = data | transform(...) | accumulate (...);

不起作用,您必須以這種不自然的方式編寫它:

const double val = accumulate(data | transform(...));

可以在此處此處找到詳細信息,但歸結為累積無法消除 2 個不同用例之間的歧義的事實。

所以這讓我想到:

如果 C++20 要求你必須使用管道來使用范圍,也就是你不能

vector<int> v;
sort(v);

但你必須寫

vector<int> v
v|sort();

那會解決歧義問題嗎?

如果是這樣,盡管對於使用std::sort和其他 STL 算法的人來說不自然,我想知道從長遠來看這是否是更好的設計選擇。

注意:如果這個問題太模糊,可以投票結束,但我覺得這是一個合理的設計問題,可以以相對公正的方式回答,特別是如果我對問題的理解是錯誤的。

您需要區分范圍算法和范圍適配器 算法是對一系列值執行通用操作的函數。 適配器是創建范圍視圖的函數,這些視圖修改范圍的表示。 適配器由|鏈接| 操作員; 算法只是常規函數。

有時,相同的概念事物可以具有算法和適配器形式。 transform既作為算法又作為適配器存在。 前者將變換存儲為輸出范圍; 后者創建輸入的視圖范圍,根據請求懶惰地計算轉換。

這些是針對不同需求和用途的不同任務。

另請注意,C++20 中沒有sort適配器 排序適配器必須創建一個視圖范圍,該范圍以某種方式混合在源范圍中的元素周圍。 它必須為新的值序列分配存儲空間(即使它只是對值的迭代器/指針/索引進行排序)。 並且排序必須在構建時完成,因此不會發生懶惰的操作。

這也是為什么accumulate不能那樣工作的原因。 這不是“歧義”的問題; 這是操作的基本性質的問題。 累加從一個范圍計算一個值; 它不會從現有范圍計算新范圍。 那是算法的工作,而不是適配器的工作。

有些任務在算法形式中很有用。 某些任務在適配器形式中很有用(您會發現很少有zip的算法)。 有些任務對兩者都有用。 但是因為它們是用於不同目的的兩個獨立概念,所以它們具有不同的調用方式。

那會解決歧義問題嗎?

是的。

如果只有一種寫東西的方式,那一種方式一定是唯一可能的解釋。 如果算法“調用”只能是對算法的部分調用,必須用|完成| 在左側有一個范圍的操作,那么你甚至永遠不會有算法調用是部分還是全部的問題。 它總是片面的。

在這個意義上沒有歧義。

但是如果你走那條路,你最終會得到這樣的結果:

auto sum = accumulate("hello"s);

這實際上並沒有將該字符串中的char相加,實際上是占位符,它正在等待一個范圍與初始值"hello"s累加。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM