[英]What do we need std::as_const() for?
C++11 給了我們std::add_const
; 使用 C++17,我們有一個新結構 - std::as_const()
。 前者只是在您提供的類型之前添加一個const
。 第二個是正確的(a 的模板)函數,而不是類型特征,它似乎做同樣的事情 - 除了當類型是右值引用時,在這種情況下它不能使用。
我不太明白提供std::as_const()
的動機。 為什么除了std::add_const
之外我們還需要它?
“需要”是一個強詞...... std::as_const
存在是因為它有用,而不是絕對必要。 由於它是一個函數而不是一個特征,我們可以使用它來“添加 const”到實際值而不是類型。
更具體地說:假設我有一些變量my_value
並且我想將其視為const
,但不復制它。 在 C++17 之前,我需要編寫:
static_cast<const MyType&>(my_value)
如果我不想明確指定類型,它將是:
static_cast<std::add_const_t<std::remove_reference_t<decltype(my_value)>> &>(my_value)
或者,如果您想低調而骯臟,並使用 C 風格的強制轉換:
(const decltype(my_value) &) (&my_value)
所有這些都很煩人和冗長。
而不是這些,現在用 C++17 編寫std::as_const(my_value)
,這就是它的全部內容。
筆記:
這個函數對右值引用是禁用的,即使它對它們工作得很好。 原因是為了幫助您避免無意中保留對暫時過去其破壞的引用。 正如@NicolBolas 解釋的那樣,如果您編寫如下內容:
for(auto &x : std::as_const(returns_container())) { /* do stuff with x */ }
然后返回的容器的生命周期在循環的第一次迭代之前結束。 很容易錯過!
有關其他 (?) 信息,請參閱此實用函數的官方命題: P007R1 ,作者 Adam David Alan Martin 和 Alisdair Meredith。
您可能想要重載 const、no-const 並強制其中一個重載:
template<class T> [[nodiscard]]
T twice(T const& t){return t + t;}
template<class T>
void twice(T& t){t += t;}
您可以通過添加const
並使用非修改重載來保護輸入。
double t = 5.;
twice(t); // t == 10
double const u = 5.;
double ux2 = twice(u); // ux2 == 10, u == 5.;
double v = 5.;
double vx2 = twice(std::as_const(v)); // vx2 == 10., v==5. It saves you from
// creating a const-reference
// `double const& ucr = u;` just to pass
// to the function.
我並不是說這是一個好的設計,只是為了說明這一點。 找到更有用的案例只是時間問題。
std::as_const
的更好名稱可能是std::protect
IMO。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.