如何将std :: array <char,n =“”>转换为char(&dest)[N]?

时间:2018-07-19 13:04:32

标签: c++ arrays c++11 reinterpret-cast stdarray

std::array<char, N>传递给 这样的功能:

template<size_t N>
void safe_func(char (&dest)[N]);

我尝试这个:

#include <array>

template <size_t N> using SafeArray = char[N];

template <size_t N> void safe_func(char (&dest)[N]) {}

int main() {
  SafeArray<10> a1;
  safe_func(a1);
  std::array<char, 10> a2;
  safe_func(*static_cast<SafeArray<10> *>(static_cast<void *>(a2.data())));
}

它有效,但是我怀疑我的演员表可能有问题, 在其他编译器或平台上(我使用了gcc / linux / amd64), 我遇到了错误的参考?

1 个答案:

答案 0 :(得分:7)

一种方法:

template<class T, size_t N>
using c_array = T[N];

template<class T, size_t N>
c_array<T, N>& as_c_array(std::array<T, N>& a) {
    return reinterpret_cast<T(&)[N]>(*a.data());
}

int main() {
    std::array<int, 2> a;
    int(&b)[2] = as_c_array(a);
}

该标准要求std::arrayaggregate,并且唯一成员是T[N]std::array::data()返回的指针。由于集合的地址与其第一个成员的地址一致,因此严格地不必调用和取消引用std::array::data(),因此reinterpret_cast<T(&)[N]>(a)也可以工作。

std::array起源于boost,其唯一目的是为内置数组begin/end/size/empty/etc.提供一个标准的容器接口(T[N]),因此没有其他用途。它没有任何开销,零成本的抽象。因此,您可以基本上来回转换boost::array<T, N>T[N],尽管这样做可能会破坏别名规则(编译器假定boost::array<T, N>T[N]引用了不同的对象,因此您需要知道如何处理您的特定情况)。

该标准放弃了所有理由,并以非常微弱和模糊的术语表达了std::array的要求。因此人们想知道那里是否真的只有T[N]成员,而不是某个满足要求的所谓的地外类型。