任意大小Boost::数组的Boost::变体

boost::variant for boost::arrays of arbitrary size

本文关键字:Boost 变体 任意大 数组      更新时间:2023-10-16

我想以

的精神创建一个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值作为模板参数的类的可行解决方案。

既然你在谈论具有静态已知容量的类型,难道你不能用一些模板元编程来摆脱这个困境吗?

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]

更新

脑波:我刚刚意识到std::array<>指定为POD(琐碎)类型。因此,布局必须是标准的,大小必须与等效的T[N]数组相同。由于这些限制,您可以安全地将任何std::array<T, M>转换为std::array<T, N>&(具有匹配的const/volatile限定),只要N>0N<=M

相反, 所需的存储空间
variant<array<T, 1>, array<T, 1>, array<T, 1>, .... array<T, 1000> >

总是,至少 sizeof array<T, 1000> +类型标识符(which())的开销。如果只有维度不同

,那么区分所有其他不同的数组<>实例化没有任何好处。

你可以这样写:

#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的函数轻松扩展到其他类型)。

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

您可能应该使用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> >