![](/img/trans.png)
[英]Difference between std::move() and std::add_rvalue_reference()
[英]question about implementation of add_rvalue_reference
cppreference中add_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 類型, T
和T&&
都是有效類型,因此兩個重載都不會 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.