c++ - std::array 存储位置如何?

标签 c++ arrays c++11

我想要一种机制,允许我将可变函数参数(所有这些参数都可以转换为某些特定的普通旧数据类型的值 F )连接到适当大小的原始数据存储中(大小大于或等于参数大小的总和)。我写了下面的代码:

#include <iostream>
#include <iterator>
#include <new>
#include <cstdlib>
#include <cassert>
#include <array>
#include <tuple>

template< typename F >
struct repacker
{

    constexpr
    repacker(F * const _storage)
        : storage_(_storage)
    {
        static_assert(std::is_pod< F >::value, "Underlying type is not a POD type.");
    }

    F * const storage_;

    template< typename... P >
    auto operator () (P && ...params) const
    {
        constexpr auto N = sizeof...(P);
        using A = std::array< F, N >; // using A = F [N]; this eliminates the problem
        static_assert(sizeof(A) == sizeof(F) * N, "This compiler does not guarantee, that this code to be working.");
#ifndef _NDEBUG
        auto a =
#else
        std::ignore =
#endif
                new (storage_) A{F(params)...};
        assert(static_cast< void * >(a) == static_cast< void * >(a->data()));
        return N;
    }

};

int main()
{
    using F = double;
    constexpr auto N = 6;
    F * a = new F[N];
    {
        F x(1.0);
        F const y(2.0); 
        repacker< F > r(a);
        auto const M = r(x, y, 3.0, 4, 5.0f, 6.0L);
        assert(M == N);
    }
    std::copy(a, a + N, std::ostream_iterator< F const & >(std::cout, " "));
    std::cout << std::endl;
    delete [] a;
    return EXIT_SUCCESS;
}

但我不确定 assert(static_cast< void * >(&a) == static_cast< void * >(a.data()));断言对所有编译器都是正确的。这是代码运行的必要条件。

断言总是正确的吗?

最佳答案

This is a necessary condition for a code to be working.

不,不是。好的,这是必要的,但这还不够。这个(非常糟糕的)代码工作的另一个必要条件是:

sizeof(std::array<F, N>) == sizeof(F) * N;

标准保证这一点。 std::array 与 C 风格数组的布局不兼容。 std::array内容是,但不是完整类型本身。

如果你想在内存中初始化你分配的位 block 中的一些对象,你应该新建一个 char[] 数组,而不是 F 数组。你应该分配这个:

char *a = new char[sizeof(std::array<F, N>)];

关于c++ - std::array 存储位置如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16606841/

相关文章:

javascript - insideHTML 和一个变量

arrays - 找到最小距离都值 pythonic

C++:从装箱元素的 vector 构造一个 Box 类型的 vector

c++ - 重载 operator << for enum 导致重复输出

c++ - 为什么在全局或外部声明结构时会出现段错误?

c++ - 传递对变量的引用

c++ - 提取基类指针

javascript - 当数组与另一个数组匹配时清空数组

c++ - constexpr for 循环编译

c++ - 列出导致线程本地单例类崩溃的析构函数