簡體   English   中英

我們需要 std::as_const() 做什么?

[英]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.

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