static_cast 原始引用之间
static_cast between primitive references
是否定义了使用 static_cast
从 const 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& 被绑定到一个临时的,或者如果它发生在 运行 时间。所以是的,您应该从值中得到 1
。 char
1 将被复制到 unsigned long long
并且 const& 将绑定到它。我不认为它不会绑定到您创建的数组。这将是完全安全的,您可以忽略上面的大部分内容。
您可以通过尝试转换为左值来稍微测试一下这个想法。不过,您不必让数据成为 constexpr
。
我认为 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.
是否定义了使用 static_cast
从 const 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& 被绑定到一个临时的,或者如果它发生在 运行 时间。所以是的,您应该从值中得到 1
。 char
1 将被复制到 unsigned long long
并且 const& 将绑定到它。我不认为它不会绑定到您创建的数组。这将是完全安全的,您可以忽略上面的大部分内容。
您可以通过尝试转换为左值来稍微测试一下这个想法。不过,您不必让数据成为 constexpr
。
我认为 C++14 中的 [expr.static.cast]/4 涵盖了这一点:
An expression
e
can be explicitly converted to a typeT
using astatic_cast
of the formstatic_cast<T>(e)
if the declarationT t(e);
is well-formed, for some invented temporary variablet
. 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 cv1T1
is created and copy-initialized from the initializer expression. The reference is then bound to the temporary.