[英]std::reference_wrapper, constructor implementation explaination
我一直試圖從這里了解std::reference_wrapper
的實現,如下所示:
namespace detail {
template <class T> constexpr T& FUN(T& t) noexcept { return t; }
template <class T> void FUN(T&&) = delete;
}
template <class T>
class reference_wrapper {
public:
// types
typedef T type;
// construct/copy/destroy
template <class U, class = decltype(
detail::FUN<T>(std::declval<U>()),
std::enable_if_t<!std::is_same_v<reference_wrapper, std::remove_cvref_t<U>>>()
)>
constexpr reference_wrapper(U&& u) noexcept(noexcept(detail::FUN<T>(std::forward<U>(u))))
: _ptr(std::addressof(detail::FUN<T>(std::forward<U>(u)))) {}
reference_wrapper(const reference_wrapper&) noexcept = default;
// assignment
reference_wrapper& operator=(const reference_wrapper& x) noexcept = default;
// access
constexpr operator T& () const noexcept { return *_ptr; }
constexpr T& get() const noexcept { return *_ptr; }
template< class... ArgTypes >
constexpr std::invoke_result_t<T&, ArgTypes...>
operator() ( ArgTypes&&... args ) const {
return std::invoke(get(), std::forward<ArgTypes>(args)...);
}
private:
T* _ptr;
};
盡管 std::reference_wrapper 的實現已在此處和此處進行了討論,但沒有一個討論我感到困惑的構造函數實現。 我的困惑是:1.)構造函數是模板 function,采用與模板 class 參數T
不同的類型參數( U
)。 我已經看到 class 的成員函數是模板函數,並且取決於不同的類型參數,然后是模板 class 的類型參數,但我想不出它在這里是如何工作的。 這里有一個相關的問題,但我無法將它與我的困惑聯系起來。 2.)我看到構造函數中的第二個類型參數被進一步用於sfinae出來的東西,但我不明白detail::FUN<T>(std::declval<U>())
是如何評估的。
有人可以解釋一下嗎?
當您想要“轉發引用”的行為時,您可以使用這種技術,在這種情況下為U&&
,但同時限制可以綁定到它的內容。
下面提供的扣除指南有助於扣除U
detail::FUN<T>(std::declval<U>())
通過選擇已刪除的重載並生成無效表達式來確保當U
被推斷為右值引用時禁用構造函數。 如果U
是另一個引用包裝器,它也會被禁用,在這種情況下應該選擇復制構造函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.