为什么 const 在像 const T& 这样的表达式中丢失,其中 T 是一个右值引用?

Why is the const lost in an expression like `const T&` where T is an rvalue reference?

我正在处理一个模板化的 class,给定一个传入类型 T,该模板需要映射到一个“安全的”const 引用。 (这基本上是为了避免在调用时将变异的能力传递给包装函数;请参阅 here 了解真实代码)。

原作者写了类似这样的东西:

template <typename T>
using SafeReference =
    std::conditional_t<std::is_scalar_v<T>, T, const T&>;

标量部分在这里并不有趣,但有趣的是 const T&。这在我看来是正确的,但事实并非如此:

struct Foo{};
using Bar = Foo&&;

// A failing static assert, and a reduced version. It turns out `const Bar&`
// is `Foo&`.
static_assert(std::is_same_v<const Foo&, SafeReference<Bar>>);
static_assert(std::is_same_v<const Foo&, const Bar&>);

我知道 Foo&& 变成 Foo& 由于 reference collapsing 的规则。我也明白 const 可能“丢失”了,因为它试图创建一个引用 const 而不是将引用类型设置为 const。但我什至不知道要 Google 才能确认这一点。

标准的哪一部分说 const 在像 const T& 这样的表达式中“丢失”,用于扩展到右值引用的模板化 T

Which part of the standard says that the const is "lost" in an expression like const T& for a templated T expanding to an rvalue reference?

来自dcl.ref/p6

If a typedef-name ([dcl.typedef], [temp.param]) or a decltype-specifier ([dcl.type.decltype]) denotes a type TR that is a reference to a type T, an attempt to create the type lvalue reference to cv TR creates the type lvalue reference to T, while an attempt to create the type rvalue reference to cv TR creates the type TR.

引用可能解释了您所看到的行为。