4

C++ の世界で、私がやろうとしていることを可能にするものはありますか?

template < typename T
         , size_t Size >
struct array
{
    constexpr T buf[Size];

    constexpr size_t size() const { return Size; }
};

template < typename T
         , size_t Size >
constexpr array<T,Size+1> push_back(array<T,Size> const& arr, T const& val)
{
    array<T,Size+1> arr_out = {{arr.buf, val}};

    return arr_out;
}

私がやろうとしているのは、他のデータで初期化された新しい配列を作成し、最後に新しい要素を配置することです。

constexpr を差し引いて、push_back 関数で初期化をループすることで動作させることができます。constexpr 関数ではそれを行うことができないようですが、これはある程度理にかなっていますが、十分に賢いコンパイラがそれを理解できると思います。

私はそれができないと確信していますが、間違っていることを示したいと思っています。

4

3 に答える 3

4

トリックを示します、イェーイ〜

template < typename T
         , size_t Size >
struct array
{
    T buf[Size]; // non-static data members can't be constexpr

    constexpr size_t size() const { return Size; }
};

namespace detail{
template< typename T, size_t N, size_t... Is>
constexpr array<T, N+1> push_back(array<T, N> const& arr, T const& val, indices<Is...>)
{
    // can only do single return statement in constexpr
    return {{arr.buf[Is]..., val}};
}
} // detail::

template < typename T, size_t Size >
constexpr array<T,Size+1> push_back(array<T,Size> const& arr, T const& val)
{
    return detail::push_back(arr, val, build_indices<Size>{});
}

実例。

于 2013-02-24T01:25:19.287 に答える
0
namespace detail_
{

template < typename T
         , size_t End >
struct push_backer
{
    template < typename Array
             , typename ... Args>
    static constexpr auto push_back(Array const& arr, Args const& ... args) -> decltype(push_backer<T,End-1>::push_back(arr, arr.buf[End-1],args...))
    {
        return push_backer<T,End-1>::push_back(arr, arr.buf[End-1], args...);
    }
};

template < typename T >
struct push_backer<T,0>
{
    template < size_t Size
             , typename ... Args>
    static constexpr array<T,Size+1> push_back(array<T,Size> const& arr, Args const& ... args)
    {
        return array<T,Size+1>{{args...}};
    }
};

}

template < typename T
         , size_t Size >
constexpr array<T,Size+1> push_back(array<T,Size> const& arr, T const& val)
{
    return detail_::push_backer<T,Size>::push_back(arr, val);
}
于 2013-02-24T01:33:51.377 に答える