采取的簽名是
template< ranges::viewable_range R, class DifferenceType >
requires /* ... */
constexpr ranges::view auto take( R&& r, DifferenceType&& count );
這是一件小事,但我想知道為什么DifferenceType不是一些 ssize 型別(實際上int64_t在現代機器上)。這只是為了避免在比較不同有符號的整數時發出警告,還是我遺漏了其他一些設計原因。我的直覺是固定型別會使錯誤訊息更容易閱讀,所以我想知道動機是什么。
如果有人對代碼示例感興趣,這里就是,感覺有點做作,因為我想保持簡短,但是很可能傳遞錯誤的型別來獲取引數,然后錯誤訊息是不可讀的(我最喜歡的部分是:
/opt/compiler-explorer/gcc-trunk-20220401/include/c /12.0.1/bits/atomic_base.h:98:3: 注意:候選:'constexpr std::memory_order std::operator|(memory_order, __memory_order_modifier )'
)。
#include <vector>
#include <iostream>
#include <ranges>
#include <string>
#include <fmt/format.h>
#include <fmt/ranges.h>
auto get_n(){
return std::string("2");
}
int main() {
std::vector v {2,3,5,7,11};
const auto n = get_n(); //oops this is std::string
auto dont_even = v | std::views::filter([](const int& i){return i%2==1;}) | std::views::take(n);
std::cout << fmt::format("{}", dont_even);
}
uj5u.com熱心網友回復:
這是一件小事,但我想知道為什么
DifferenceType不是一些 ssize 型別(實際上int64_t在現代機器上)。這只是為了避免在比較不同有符號的整數時發出警告,還是我遺漏了其他一些設計原因。
不同范圍配接器的迭代器有不同difference_type的 s。計算difference_type有時并不像你想象的那么簡單。
舉iota_view個例子,標準特意用它IOTA-DIFF-T(W)來計算difference_type,這使得difference_typeof iota_view<uint64_t>is__int128和difference_typeofiota_view<__int128>甚至是__detail::__max_diff_typelistdc 中自定義的。
這就是為什么第二個引數views::take是模板而不是特定整數型別的原因,但請注意,標準對 [range.take.overview] 也DifferenceType有限制:
該名稱
views?::?take表示范圍配接器物件 ([range.adaptor.object])。LetEandFbe 運算式, letTberemove_-cvref_-t<decltype((E))>和 letDberange_-difference_-t<decltype((E))>。如果decltype((F))不建模convertible_-to<D>,views?::?take(E, F)則格式不正確。
這要求 theDifferenceType必須可轉換為R's difference_type,這也允許您
auto r = std::views::iota(0)
| std::views::take(std::integral_constant<int, 42>{});
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/455276.html
