簡體   English   中英

我什么時候應該使用remove_reference和add_reference?

[英]When should I use remove_reference and add_reference?

我正在看[VC10的] unique_ptr,他們做了一些我不明白的事情:

typedef typename tr1::remove_reference<_Dx>::type _Dx_noref;

_Dx_noref& get_deleter()
    {   // return reference to deleter
    return (_Mydel);
    }

unique_ptr(pointer _Ptr,
    typename _If<tr1::is_reference<_Dx>::value, _Dx,
        const typename tr1::remove_reference<_Dx>::type&>::_Type _Dt)
    : _Mybase(_Ptr, _Dt)
    {   // construct with pointer and (maybe const) deleter&
    }

typename tr1::add_reference<_Ty>::type operator*() const
    {   // return reference to object
    return (*this->_Myptr);
    }

不只是寫_Dx&或_Ty&是同一回事?

我實際上明白他們為什么在這里做到了:

unique_ptr(pointer _Ptr, typename tr1::remove_reference<_Dx>::type&& _Dt)
    : _Mybase(_Ptr, _STD move(_Dt))
    {   // construct by moving deleter
    }

get_deleter

從返回類型中刪除任何引用,然后添加引用。 在符合C ++ 11的情況下,將&添加到現有的& (或&& )會產生& 然而,在C ++ 03中,這將形成對引用類型的引用,這是非法的。 可能MSVC正在使用舊規則,或者代碼是在它執行時編寫的,因為它是無害的。

構造函數

在這里,他們刪除引用,添加const ,然后添加引用,以便通過const引用傳遞。 這是因為直接向引用類型添加const 什么都不做 (§8.3.2/ 1)在C ++ 11或C ++ 03中,參數聲明有效,但如果未刪除和替換引用,則不會添加const

operator*

這與get_deleter基本相同,但它們以不同的方式進行,並且_Ty不能作為開頭的引用類型。 它看起來像_Ty&就足夠了,但這是他們的特權。

這里有一個例子,可能是原型,為什么我們需要remove_reference ,在std::move的實現中:目標是根據推導出的函數參數類型返回一個rvalue-reference類型。

示例: Foo x; move(x); Foo x; move(x); 這里move(x)應該返回一個類型Foo&& 但是move的論點是Foo&類型的表達。 那么move功能如何推導出正確的類型呢?

第一次嘗試是使用普通模板參數推導並使用強制轉換:

template <typename T> T && move(??? x) { return static_cast<T&&>(x); }

但應該怎么做??? 如果我們說T x ,那么T將被推斷為Foo& ; 如果我們說T & x ,那么T = Foo ,如果我們說T && x ,它將完全不匹配。 第二個版本T & x似乎很有用。

但是這個函數在rvalues上不起作用(例如move(Foo(...)) 。在這種情況下,我們想要T && x使得T = FooT&& = Foo&&根據需要。我們可以有兩個重載,但有多個重載是不可取的,因為它不必要地增加了復雜性。最后,如果有人明確指定模板參數move<Foo&>(x) ,該函數將永遠不會工作,因為當T = Foo& ,則T&& = Foo&以及。

所以來自remove_reference

template <typename T>
typename std::remove_reference<T>::type && move(T && x)
{
    return static_cast<typename std::remove_reference<T>::type &&>(x);
}

首先,新的參考折疊規則意味着在兩種情況下T被推斷為Foo&Foo&& 然后, remove_reference剝離引用並在任何情況下給出類型Foo ,並添加&&使得所需的Foo&&返回類型。

在一個過於簡化的摘要中:我們需要remove_reference因為(Foo&)&&Foo&而不是Foo&& 如果您編寫的模板代碼需要模板參數的基本類型(可以推導為U&U&& ,則可以使用此模型。

template class add_reference具有voidconst voidconst volatile void因為不允許引用void type (void&) 如果使用_Ty& ,則在_Ty = void時會產生編譯錯誤。

暫無
暫無

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

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