初始化一组非琐碎的可构造对象

时间:2015-09-29 13:00:38

标签: arrays c++11 constructor reference

我有一个类Foo,它需要构建一个引用(它将用于处理该内存空间)

template<typename T>
class Foo {
  public:
    Foo(T& value) : _value(value) {}
    ...
  private:
    T& _value;
};

我还有一个多个T

实例的线性内存空间
std::array<T, SIZE> buffer;

我想要构建的是Foo类型的对象数组,它映射缓冲区的不同实例。这意味着必须使用正确的引用构建Foo的每个实例。

std::array<Foo<T>, SIZE> operators;

仍然,operators无法进行简单的初始化,我可以设法通过“映射”来构建它。缓冲通过&#39; Foo&#39;构造

有什么办法吗?我尝试使用std::forwardstd::initializer_list,但这些不能从我的缓冲区构建。

请注意,我需要将缓冲区保持对齐以进行通信,并且我将重载Foo类以实现我的数组的不同元素的不同行为。

4 个答案:

答案 0 :(得分:2)

std::array必须知道初始化如何构造引用。喜欢使用这样的指针:

template<typename T>
class Foo {
  public:
    Foo() { } // used by std::array to create Foo<T>
    Foo(T& value) : _value(&value) {}
    operator T&() { return *_value; } // never call this on uninitialised objects
  private:
    T* _value = nullptr;
};

您可以做的是创建一个静态对象来预先初始化您的参考。

template<typename T>
class Foo {
  static T _default; // default-object used to initialize the reference
  public:
    Foo() { } // used by std::array to create Foo<T>
    Foo(T& value) : _value(value) {}

    T& _value = _default;
};

int a = 0;
std::array<Foo<int>, 10> arr;
arr[0]._value = a;

答案 1 :(得分:1)

不幸的是,没有办法直接初始化operators数组。

我能想到的唯一解决方案是使Foo默认可构造,然后循环buffer(使用循环或例如std::transform)并“初始化”{}中的每个条目{1}}使用作业。

这样的东西
operators

答案 2 :(得分:0)

一种方法是拼出初始化元素:

T a, b;

std::array<Foo<T>, 5> a = { {
    Foo<T>(a), Foo<T>(b), Foo<T>(a), Foo<T>(b), Foo<T>(a) } };

另一种方法是将存储与对象构造分开,并手动管理数组元素的生命周期。

答案 3 :(得分:0)

以下是如何使用indices技巧构建数组的示例:

#include <array>
#include <iostream>

template<typename T>
class Foo {
    public:
        Foo(T& value) : _value(value) {}
        ...
    private:
        T& _value;
};

// Typical varadic indices builder
template<size_t... Is> struct Indices { };

template <size_t count,size_t... Is>
struct BuildIndices : BuildIndices<count-1,count-1,Is...> { };

template<size_t... Is>
struct BuildIndices<0,Is...> : Indices<Is...> { };


// Helper function
template <typename T,size_t... Is>
static std::array<Foo<T>,sizeof...(Is)>
    make_foo_array_with_indices(
            std::array<T,sizeof...(Is)> &values,
            Indices<Is...>
            )
{
    return {{values[Is]...}};
}

template <typename T,size_t count>
static std::array<Foo<T>,count>
    make_foo_array(std::array<T,count> &values)
{
    return make_foo_array_with_indices(values,BuildIndices<count>());
}


int main()
{
    std::array<int,4> buffer = {3,1,4,1};
    std::array<Foo<int>,4> operators = make_foo_array(buffer);
}