[英]Template Reference Collapsing Dropping cv-qualifiers for const Reference Return Type
[英]cv-qualifiers and rvalue-reference
假設我們有如下所示的這段代碼,問題是為什么不保留“c”的 cv 限定符(const),其行為與“v”不同?
int main(int argc, char **argv) {
int x{};
int y{};
const auto [v] = std::tuple<int>(x);
const auto [c] = std::tuple<int&&>(std::move(y));
decltype(v) vv = 10; // vv -> const int;
decltype(c) cc = 100; // cc -> int&&;
return 0;
}
另外,我可以像下面這樣用模板參數推導模擬相同類型的推導過程嗎?
template<class T>
void foo(T t) { // here should be T rather than universal reference;
// mimic the same behavior as above somehow ...
}
疑點二:
對於下面的代碼,似乎“結構化綁定”的“自動”推斷與“自動”的正常用法不一致?
我期望的是,對於第一個“auto”, decltype(v)
應該是const int的類型,而不是像第二個那樣的int& ,因為我沒有在“auto”旁邊指定“&”。所以,任何特殊規則“結構化綁定”與“自動”?
int main(int argc, char **argv) {
int x{};
const auto [v] = std::tuple<int&>(x); // v -> int&;
static_assert(std::is_same_v<decltype(v), int&>);
int& rx = x;
const auto c = rx; // c -> const int;
static_assert(std::is_same_v<decltype(c), const int>);
return 0;
}
給定
const auto [v] = std::tuple<T>(x);
decltype(v)
類型是T const
,即const
限定的T
。 如果T
是int
,則decltype(v)
是int const
(也可以寫成const int
)。 如果T
是int&&
,則decltype(v)
是int&& const
,它是int&&
(不是const int&&
,它是對const int
的引用)。 int&& const
類型與int&&
&& 相同,因為引用總是有效的const
。 它們引用的對象可能是可變的,但 C++ 中的引用本身是不可變的。
據我所知,使用沒有通用引用的模板類型推導,您無法模仿這種類型轉換(將const
添加到T
)。 但是有一個類型轉換特征std::add_const_t<T>
。
懷疑 2 的更新
結構化綁定
const auto [v] = std::tuple<int&>(x); // v -> int&;
不類似於
int& rx = x;
const auto c = rx; // c -> const int;
相反,它類似於
const auto e = std::tuple<int&>(x);
auto&& v = std::get<0>(std::move(e));
const 限定適用於元組,而不適用於 v 的綁定。引用限定符或缺少它適用於元組。 v 的綁定始終是類引用的。
奇怪的是實際上在另一種情況下:
const auto [v] = std::tuple<int>(x);
仍然 v 類似於引用,但decltype(v)
是int
。 不同之處在於結構化綁定中的綁定是別名,而不是引用。 它們是所指事物的不同名稱,但它們本身沒有引用類型。
所以:
const auto [v] = std::tuple<T>(x);
最類似於:
const auto e = std::tuple<T>(x);
auto&& r = std::get<0>(std::move(e));
(introduce v as a name for that which r refers to)
第三行不是我們有能力寫的。
正如 Jeff Garret 所提到的, const
將適用於推導出的整個auto
類型。 例如,如果類型是int&
,那么const auto
將與auto const
相同,這與int& const
相同。 引用是const
,而不是數據。
現在,你能做些什么呢? 您不必停止使用auto
。 您可以簡單地指定const auto&
。 auto
將推斷為int
,整個類型將是const int&
(等效於int const&
)。 這就是你如何讓你的數據成為常量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.