constexpr和endianness [英] constexpr and endianness

查看:180
本文介绍了constexpr和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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆