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