[英]Can Niebloids be passed where Callables is required?
一般來說,除非明確允許,否則 C++ 程序嘗試獲取標准庫 function 的指針的行為是未指定的。 這意味着在將它們作為Callable傳遞之前應格外小心。 相反,通常最好將它們包裝在 lambda 中。
有關該主題的更多信息: 我可以獲取標准庫中定義的 function 的地址嗎?
然而,C++20 在Range-v3 庫的基礎上引入了Constrained algorithms或 ranged algorithms ; 其中類似函數的實體,例如std::ranges::sort
和std::ranges::transform
,被引入為 Niebloids。
雖然原始庫為算法庫中的每個函數創建了一個仿函數 class,而每個 niebloids,例如ranges::sort
,只是對應仿函數 class 的一個名為 object 的函數; 該標准沒有具體說明它們應該如何實施。
所以問題是,是否指定/明確允許將 Niebloid 作為Callable傳遞的行為,例如std::invoke(std::ranges::sort, my_vec)
?
所有規范都在[algorithms.requirements]中說:
依賴於參數的名稱查找 ([basic.lookup.argdep]) 找不到本條款中
std::ranges
命名空間中定義的實體。 當通過 function 調用 ([expr.call]) 中后綴表達式的非限定 ([basic.lookup.unqual]) 名稱查找找到時,它們會禁止參數相關的名稱查找。
今天,實現它的唯一方法是讓它們成為對象。 但是,我們沒有指定這些對象的任何進一步行為。
所以這:
std::invoke(std::ranges::sort, my_vec)
會起作用,僅僅是因為在引用它之后它會簡單地評估為std::ranges::sort(my_vec)
,並且沒有辦法真正阻止它起作用。
但其他用途可能不會。 例如, std::views::transform(r, std::ranges::distance)
未指定工作,因為我們沒有說明std::ranges::distance
是否可復制 - std::ranges::size
是自定義點 object,因此可復制,但std::ranges::distance
只是一種算法。
MSVC 實現試圖嚴格遵守有限規范,並且其std::ranges::distance
實現不可復制。 另一方面,libstdc++ 只是使它們成為空對象,因此views::transform(ranges::distance)
只是通過不被主動拒絕的方式工作。
所有這些要說的是:一旦你擺脫了直接編寫std::ranges::meow(r)
(或者在using
或using namespace
之后編寫meow(r)
),你就有點靠自己了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.