将struct转换为uint8_t的constexpr数组

时间:2018-01-05 10:28:58

标签: c++ arrays templates c++17 constexpr

我需要从constexpr struct中创建constexpr字节数组。

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="ctrl">
  <input type="file" files-input ng-model="files" multiple />
  <div ng-repeat="file in files">
    <div>{{ file.name }} <a ng-click="deleteFile(file)" href="">Delete</a></div>
    <br/>
  </div>
</div>

我试图从联合中提取它:

#include <array>

template<typename T>
constexpr std::array<uint8_t, sizeof(T)> o2ba(const T o) {
    return {};
}

struct A {
    int a;
};

int main() {
    constexpr A x{ 1 };
    constexpr auto y = o2ba(x); // y == { 0x01, 0x00, 0x00, 0x00 } for little endian
    return 0;
}

但是gcc和msvc编译器都无法访问d而不是初始化的o成员。它在初始化非constexpr对象时起作用,如下所示。

template<typename T>
union U {
    T o;
    std::array<uint8_t, sizeof(T)> d;
};

template<typename T>
constexpr std::array<uint8_t, sizeof(T)> o2ba(const T o) {
    return U<T>{o}.d;
}

但这不是我需要的。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:2)

你想要的是不可能的。在您的代码中,您尝试在constexpr上下文中访问已初始化的成员,这很好。错误是您然后尝试访问非活动成员,[expr.const#2.8]不允许这样做:

  

表达式e是核心常数表达式,除非评估   e,遵循抽象机器的规则,将评估其中一个   以下表达式:

     

...

     
      
  • 应用于glvalue的左值到右值转换,该glvalue引用联合或其子对象的非活动成员;
  •   

现在另一种方法是尝试通过reinterpret_cast,即reinterpret_cast<const uint8_t*>(&a),以旧时尚的方式将对象序列化为字节。同样reinterpret_cast允许在constexpr上下文中允许每2.15(同一部分)。我怀疑你不能这样做的原因是因为它不可移植。