2

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?

9
  • 2
    Why do you want to be able to initialize the slice from an initializer list if it makes no sense? Commented Nov 7, 2018 at 7:17
  • Say I have a function that takes a Slice, and I want to pass an initializer list instead of explicitly creating an array/list before the call. void Foo(Slice<int> bar) { ... } then Foo({1, 2, 3}); Commented Nov 7, 2018 at 7:27
  • Then why not disallow it by not having a std::initializer_list constructor? Commented Nov 7, 2018 at 7:28
  • 4
    You can't take ownership of the initializer list's underlying array. That's a non-starter. Commented Nov 7, 2018 at 7:41
  • 1
    Why not to use a variable to hold an initializer_list? auto x = {1, 2, 3}; Slice<i32> indices(x);. Then it will be a view into x. Commented Nov 7, 2018 at 7:47

1 Answer 1

0

You definitely want to copy those temporaries. You can use dynamic allocation in this case and a flag to signal the ownership:

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]; }
};
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.