![](/img/trans.png)
[英]Const temporary from template type and why use 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_const
,add_volatile
,add_cv
和add_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.