boost :: variant for boost ::任意大小的数组

时间:2014-05-12 11:18:39

标签: c++ arrays boost

我想以

的精神创建一个boost::variant
typedef boost::variant<boost::array<int, 1>, boost::array<int, 2>, boost::array<int, 3>, ... > any_int_array;

N推广到模板的第二个值。换句话说,boost::variant包含任意大小的数组。这可能吗?

请注意,在上面的示例中,boost::array是我的一个案例,但它需要是一个可行的解决方案,适用于将int值作为模板参数的任何类。

3 个答案:

答案 0 :(得分:2)

既然您正在谈论具有静态已知容量的类型,那么您是否可以通过一些模板元编程来挖掘这个漏洞?

Live on Coliru

#include <boost/variant.hpp>
#include <boost/array.hpp>
#include <bitset>
#include <iostream>

template <template <typename, size_t> class T, typename V, size_t N>
    void foo(T<V, N> const& something)
    {
        std::cout << __LINE__ << ": " << __PRETTY_FUNCTION__ << "\n";
    }

template <template <size_t> class T, size_t N>
    void foo(T<N> const& something)
    {
        std::cout << __LINE__ << ": " << __PRETTY_FUNCTION__ << "\n";
    }

int main()
{
    boost::array<int, 67> a;
    boost::array<double, 78> b;
    std::bitset<47> c;

    foo(a);
    foo(b);
    foo(c);
}

打印

9: void foo(const T<V, N> &) [T = array, V = int, N = 67]
9: void foo(const T<V, N> &) [T = array, V = double, N = 78]
15: void foo(const T<N> &) [T = bitset, N = 47]

更新

Brainwave:我刚刚意识到std::array<> 指定是一个POD(普通)类型。因此,布局必须是标准的,并且必须的大小与等效的T[N]数组相同。由于这些限制,您可以安全将任何std::array<T, M>投射到std::array<T, N>&(具有匹配的 const / volatile 资格认证),只要{{1} }和N>0

相反,

所需的存储空间
N<=M
对于类型鉴别器(variant<array<T, 1>, array<T, 1>, array<T, 1>, .... array<T, 1000> > ),

始终至少 sizeof array<T, 1000> +开销。在区分所有其他不同的数组&lt;&gt;之间没有任何好处。实例化,如果只是尺寸变化

答案 1 :(得分:2)

您可以按如下方式编写:

#include <boost/array.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/variant.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector/vector0.hpp>
#include <boost/mpl/size_t.hpp>

struct TransformToArray {
    template<typename N>
    struct apply {
        typedef boost::array<int, N::value> type;
    };
};

namespace mpl = boost::mpl;
//As this value is increased, compilation time also increases (by a large amount)
const std::size_t MaxValue = 100;
typedef typename mpl::transform<
    mpl::range_c<std::size_t, 0, MaxValue>,
    TransformToArray,
    mpl::back_inserter<mpl::vector0<>>
>::type Arrays;


int main() {
    boost::make_variant_over<Arrays>::type variant;
}

(通过编写更多struct TransformToArray - 类似函数,可以将其扩展到其他类型。

这可能没用,因为编译时间很荒谬。

答案 2 :(得分:0)

您可能应该使用boost::container::static_vector

http://www.boost.org/doc/libs/1_55_0/doc/html/container/non_standard_containers.html#container.non_standard_containers.static_vector

http://www.boost.org/doc/libs/1_54_0/doc/html/boost/container/static_vector.html

static_vector从堆栈中分配。

您可以使用static_vector<T, 1000>代替variant<array<T, 1>, array<T, 2>, array<T, 1>, .... array<T, 1000> >