簡體   English   中英

關於 add_rvalue_reference 實施的問題

[英]question about implementation of add_rvalue_reference

cppreferenceadd_rvalue_reference的實現如下。 int參數(即 0)與無參數的需要是什么?

namespace detail {
 
template <class T>
struct type_identity { using type = T; }; // or use std::type_identity (since C++20)
 
template <class T>
auto try_add_rvalue_reference(int) -> type_identity<T&&>;
template <class T>
auto try_add_rvalue_reference(...) -> type_identity<T>;
 
} // namespace detail
 
 
template <class T>
struct add_rvalue_reference : decltype(detail::try_add_rvalue_reference<T>(0)) {};

如果實現是這樣的:

namespace detail {
 
template <class T>
struct type_identity { using type = T; }; // or use std::type_identity (since C++20)
 
template <class T>
auto try_add_rvalue_reference() -> type_identity<T&&>;
template <class T>
auto try_add_rvalue_reference() -> type_identity<T>;
 
} // namespace detail
 
 
template <class T>
struct add_rvalue_reference : decltype(detail::try_add_rvalue_reference<T>()) {};

然后使用例如T一個 object 類型, TT&&都是有效類型,因此兩個重載都不會 SFINAE 調用detail::try_add_rvalue_reference<T>() 兩種重載都是可行的。 但是現在因為沒有 function 參數/參數對來區分它們,所以兩者在重載解決方案方面同樣出色,沒有應用決勝局,因此調用detail::try_add_rvalue_reference<T>()將是模棱兩可的。

使用int...作為參數,如果兩者都可行,則int重載將始終被認為是重載解決方案的更好候選者。 目的是只要T&&是有效類型,就會選擇它。

此實現利用SFINAE並依賴於重載解決方案以解決替換不失敗的情況。 為了使重載決議在可行的函數之間進行選擇,必須至少有一個參數。 參數的類型是任意的; int很方便。

第一次超載

template <class T>
auto try_add_rvalue_reference(int) -> type_identity<T&&>;

並不總是存在。 如果將T代入返回類型失敗,則不是錯誤。 跳過此模板而不是錯誤,不會為該特定T生成 function 。

第二次超載

template <class T>
auto try_add_rvalue_reference(...) -> type_identity<T>;

確實存在,但它是一個普遍的后備。 也就是說,當涉及到重載決議時,只要有一個參數,它就會輸給幾乎所有的東西。 (當沒有提供參數時, (...) () ) 聯系在一起。)

如果僅存在第二個重載,則調用 function 將調用該重載(因為沒有其他選擇)。 因此,返回值的聲明類型是T 對於這種情況,參數的存在無關緊要。

如果兩個重載都存在,那么使用int參數調用 function 將調用第一個重載(因為第二個在重載決議中輸給了第一個)。 因此,返回值的聲明類型是T&& 如果沒有參數,則重載解析將無法在兩個重載之間進行選擇,編譯將失敗。

替換失敗不是錯誤,但重載解析失敗是。

暫無
暫無

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

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