1

可変引数関数パラメーター (それらはすべて、特定の単純な古いデータ型の値に変換可能です) を適切なサイズの生データ ストレージに連結できるメカニズムが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()));主張がすべてのコンパイラに当てはまるかどうかはわかりません。これは、コードが機能するための必要条件です。

主張は常に真ですか?

4

3 に答える 3