static_cast 原始引用之间

static_cast between primitive references

是否定义了使用 static_castconst unsigned char& 转换为 const unsigned long long&

constexpr unsigned char arr[sizeof(unsigned long long)]{ 1 };
constexpr bool value = static_cast<const unsigned long long&>(arr[0]) == 1;

加入int main(){},这在 Coliru、Ideone 和 VS2015 上编译时没有错误或警告。这到底是安全的,还是不安全但不需要报错的?

奖励:我没想到 arr[0] 会是一个常量表达式,但是使用 value 作为常量表达式可以正常工作。是因为arr是数组吗?

* 它是未定义的,因为您正在通过对另一种类型的引用来使用一种类型。 * 您使用了强制转换,因此如果编译器可以执行该强制转换,它应该信任您。 * 它通常会按照您似乎期望的方式工作,除了我怀疑大多数架构上的值是否正确。

实际上我认为这里发生的是你强制转换的 const& 被绑定到一个临时的,或者如果它发生在 运行 时间。所以是的,您应该从值中得到 1char 1 将被复制到 unsigned long long 并且 const& 将绑定到它。我不认为它不会绑定到您创建的数组。这将是完全安全的,您可以忽略上面的大部分内容。

您可以通过尝试转换为左值来稍微测试一下这个想法。不过,您不必让数据成为 constexpr

http://ideone.com/TxYose

我认为 C++14 中的 [expr.static.cast]/4 涵盖了这一点:

An expression e can be explicitly converted to a type T using a static_cast of the form static_cast<T>(e) if the declaration T t(e); is well-formed, for some invented temporary variable t. The effect of such an explicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion.

这将您的代码定义为等同于:

constexpr unsigned char arr[sizeof(unsigned long long)]{ 1 };

const unsigned long long &t (arr[0]);

constexpr bool value = (t == 1);

第二行现在很熟悉了:在 [dcl.init.ref]/5:

下允许从不同(非引用相关)类型的值初始化 const 引用

If T1 is a non-class type, a temporary of type cv1 T1 is created and copy-initialized from the initializer expression. The reference is then bound to the temporary.