将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), 我遇到了错误的参考?
答案 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::array
是aggregate,并且唯一成员是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]
成员,而不是某个满足要求的所谓的地外类型。