constexpr和endianness [英] constexpr and endianness
问题描述
在C ++编程世界中不时出现的一个常见问题是编译时确定字节序。通常这是用几乎不可移植的#ifdefs。但是C ++ 11 constexpr
关键字和模板专门化是否为我们提供了更好的解决方案?
A common question that comes up from time to time in the world of C++ programming is compile-time determination of endianness. Usually this is done with barely portable #ifdefs. But does the C++11 constexpr
keyword along with template specialization offer us a better solution to this?
它是合法的C ++ 11做一些像:
Would it be legal C++11 to do something like:
constexpr bool little_endian()
{
const static unsigned num = 0xAABBCCDD;
return reinterpret_cast<const unsigned char*> (&num)[0] == 0xDD;
}
然后为两个字节序类型专门化一个模板:
And then specialize a template for both endian types:
template <bool LittleEndian>
struct Foo
{
// .... specialization for little endian
};
template <>
struct Foo<false>
{
// .... specialization for big endian
};
然后执行:
Foo<little_endian()>::do_something();
推荐答案
假设 N2116 是合并的措辞,那么你的例子是不成立的在C ++中没有合法/非法的概念)。 [decl.constexpr] / 3的建议文本表示
Assuming N2116 is the wording that gets incorporated, then your example is ill-formed (notice that there is no concept of "legal/illegal" in C++). The proposed text for [decl.constexpr]/3 says
- 语句形式
{return expression; }
其中expression是一个潜在的常数表达式(5.19);
您的函数违反了要求,因为它也声明了一个局部变量。
Your function violates the requirement in that it also declares a local variable.
编辑:此限制可以通过移动num以外的函数来克服。因为表达式需要是一个潜在的常量表达式,定义为
Edit: This restriction could be overcome by moving num outside of the function. The function still wouldn't be well-formed, then, because expression needs to be a potential constant expression, which is defined as
表达式是一个潜在的常数表达式,如果它是一个常量
表达式,当所有出现的函数参数被替换为
时,由适当类型的任意常数表达式。
An expression is a potential constant expression if it is a constant expression when all occurrences of function parameters are replaced by arbitrary constant expressions of the appropriate type.
IOW, reinterpret_cast< const unsigned char *> (& num)[0] == 0xDD
必须是一个常量表达式。然而,它不是:& num
将是地址常量表达式(5.19 / 4)。然而,对于常量表达式不允许访问这样的指针的值:
IOW, reinterpret_cast<const unsigned char*> (&num)[0] == 0xDD
would have to be a constant expression. However, it is not: &num
would be a address constant-expression (5.19/4). Accessing the value of such a pointer is, however, not allowed for a constant expression:
下标运算符[]和类成员访问。和
运算符,&
和*
一元运算符和指针转型(除了dynamic_casts,5.2。 7)可以用于创建
地址常量表达式,但是不能通过使用这些运算符来访问对象的值。
The subscripting operator [] and the class member access . and operators, the
&
and*
unary operators, and pointer casts (except dynamic_casts, 5.2.7) can be used in the creation of an address constant expression, but the value of an object shall not be accessed by the use of these operators.
编辑:上述文本来自C ++ 98。显然,C ++ 0x更允许它允许常量表达式。该表达式涉及数组引用的左值到右值转换,除非
Edit: The above text is from C++98. Apparently, C++0x is more permissive what it allows for constant expressions. The expression involves an lvalue-to-rvalue conversion of the array reference, which is banned from constant expressions unless
它应用于左值有效整数类型,将
引用到非易失性常量变量或静态数据成员初始化
与常量表达式
it is applied to an lvalue of effective integral type that refers to a non-volatile const variable or static data member initialized with constant expressions
我不清楚(& num)[0]
是指一个常量变量,还是只有一个字面值 num
是指这样的变量。如果(& num)[0]
是指那个变量,那么不清楚 reinterpret_cast< const unsigned char * (&#)[0]
still指 num
。
It's not clear to me whether (&num)[0]
"refers to" a const variable, or whether only a literal num
"refers to" such a variable. If (&num)[0]
refers to that variable, it is then unclear whether reinterpret_cast<const unsigned char*> (&num)[0]
still "refers to" num
.
这篇关于constexpr和endianness的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!