![](/img/trans.png)
[英]Why is the pipe operator not working when I use ranges in 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.