首页 > 解决方案 > Implementing an initializer-list constructor that doesn't copy the elements

问题描述

I have a small Slice class that I use for functions that want to take a 'list' of items. It doesn't store any items, but is just a view into some existing list.

#include <initializer_list>

template<typename T>
struct Slice
{
    u32 length;
    T*  data;

    Slice(T& element) { length = 1; data = &element; }

    template<typename T, u32 Length>
    Slice(T(&arr)[Length]) { length = Length; data = arr; }

    inline T& operator [](u32 i) { return data[i]; }
};

I'm trying to make it possible to construct from an initializer list. Like so

Slice<i32> indices = { 0, 1, 2, 2, 3, 0 };

So I tried adding a constructor that takes an initializer_list

    template<typename T>
    Slice(std::initializer_list<T> initList) { length = initList.size(); data = (T*) initList.begin(); }

But, I think this is ill-formed because the initializer_list is a temporary value that will go out of scope after the assignment. Further, the Slice data is not strictly const and it appears that initializer_lists are.

Is there a proper way to implement this behavior?

标签: c++c++14initializer-list

解决方案


你肯定想复制那些临时的。在这种情况下,您可以使用动态分配和一个标志来表示所有权:

template<typename T>
struct Slice
{
private:
    u32 length;
    T*  data;
    bool owns= false;

public:
    Slice(T& element) { length = 1; data = &element; }

    template<u32 Length>
    Slice(T(&arr)[Length]) { length = Length; data = arr; }

    Slice(std::initializer_list<T> initList): length(initList.size()), owns(true)
      { data= new T[length]; std::copy(initList.begin(),initList.end(),data); }

    ~Slice() { if (owns) delete[] data; }

    inline T& operator [](u32 i) { return data[i]; }
};

推荐阅读