簡體   English   中英

std :: add_const和類似的用例

[英]Use cases for std::add_const and similar

<type_traits>某些類型轉換也可以使用核心語言語法來表示(例如std::add_const<T>::type is /似乎與const T等效)。 Dtto代表std::add_lvalue_reference ,也許還有其他。 這些類型特征有什么用?

我完全理解該標准將在沒有它們的情況下提供“不完整的工具箱”,並且我可以想象以元方式使用,如下所示:

template<typename In, template <typename> class Modifier>
struct Apply {
  typedef typename Modifier<T>::type Out;
};

Apply<int, std::add_const>

這些特性是否還有其他用例可以用句法表達,或者只是出於“完整感”而包括在內,還是偶爾用於元使用?

這些特性來自Boost以及將其添加到標准N1345中的提議 ,引用了Andrei Alexandrescu的話:

“我理解添加add_constadd_volatileadd_cvadd_pointer ,但是我主張消除它們。語言提供的等效項只是更簡單,更好。”

相同的建議也給出了以下理由:

作者的注釋:從表面上講,add_const,add_volatile和add_cv類無關緊要,因為,例如,對於所有T,add_const :: type與T const相同(當前不適用於函數類型-但問題295解決了此問題 )。 但是,boost的經驗是,由於以下原因,一些用戶要求這些模板出現在庫中:(a)一些用戶發現這些模板更明確-特別是在組合轉換模板時,用戶喜歡“內置”這些模板提供的“文檔”。 (b)並非所有用戶都知道允許cv限定引用是無效的,或者不允許cv限定已經是cv限定的類型,並且無效。 (c)當cv限定作為引用的類型或已經具有cv限定符的類型時,編譯器可能會發出警告,可以實現這些模板,以便在這些情況下禁止顯示這些消息。

另外,對於add_reference (在標准中重命名為add_lvalue_reference ):

作者的注釋:add_reference模板是boost類型特征庫背后的原始動機之一。 但是, 發布106的決議使模板看起來在很大程度上是多余的。 盡管如此,當在模板代碼中無意中創建對引用的引用時,add_reference可能在抑制編譯器警告方面很有用。

這些特征僅供偶爾使用。 這使得在元編程中傳輸所需的cv限定詞成為可能。

template<class T,template<class> class Trait>
struct transform
{
  /* working with T creating newT*/

  typedef Trait<newT>::type type;
};

template<class T>
struct special_transform
  : transfrom<T, std::add_const>
{};

在這種情況下,您無法將std::add_const替換為const

add_const可用於解決類型推導沖突。

template <typename T>
class wrapper;

template <typename T>
bool operator==(wrapper<T> const& w, T const& t);

如果使用wrapper<T const>則會出現問題:

wrapper<int const> w = { 42 };
assert(w == 42); // Error: conflicting deduced types

T同時被推導為int int const 可以使用add_const解決:

template <typename T>
bool operator==(wrapper<T> const& w, add_const_t<T>& t);

我知道的唯一用例如下所示:

struct F
{
    bool f() const { return true; }
    bool f() { return false; }
};
assert(!F{}.f())
assert(std::add_const_t< F >{}.f());

還需要測試cv-ref合格的成員函數的功能,這可能因不同的重載而有所不同(僅對於lref合格的現代C ++具有方便的std::as_const函數):

struct F
{
    int g() & { return 1; }
    int g() const & { return 2; }
    int g() && { return 3; }
    int g() const && { return 4; }
};
F f;
assert(f.g() == 1);
assert(std::as_const(f).g() == 2);
assert(F{}.g() == 3);
assert(std::add_const_t< F >{}.g() == 4); // rarely needed, but if needed, then it helps

暫無
暫無

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

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