2016-11-14 2 views
0

Я пишу обертку, которая для целей этого вопроса не делает ничего, кроме обертывания SequenceContainer (http://en.cppreference.com/w/cpp/concept/SequenceContainer) и воспроизводит все функциональные возможности концепции SequenceContainer, которую предлагает упакованный контейнер.Как написать оболочку для конструктора инициализации списка std :: array?

Моя попытка написать такую ​​обертку выглядит следующим образом:

template<class Container> 
class SequenceContainerWrapper 
{ 
    Container cont; 
public: 
    using value_type = typename Container::value_type; 
    using reference = typename Container::reference; 
    using size_type = typename Container::size_type; 
    SequenceContainerWrapper(initializer_list<value_type> init) : cont(init) {} 
    reference operator[] (size_type n) {return cont[n];} 
    // lots of other code that does nothing but wrapping 
}; 

И да - я могу использовать его, например, с std::vector. Ниже код компилируется и работает, как ожидалось (http://ideone.com/sYeIeJ):

int main() 
{ 
    SequenceContainerWrapper<vector<int>> vec({1,2,3,4}); 
    cout << vec[2] << '\n'; 
} 

Однако, этот конструктор не будет работать с std::array. Этот фрагмент кода не компилировать (http://ideone.com/5nZhar):

int main() 
{ 
    SequenceContainerWrapper<array<int, 4>> arr({1,2,3,4}); 
    cout << arr[2] << '\n'; 
} 

Это потому, что (http://en.cppreference.com/w/cpp/concept/SequenceContainer#cite_note-1):

станд :: массив поддерживает назначение из рамно-Init-лист, но не из станд :: initializer_list

Так как я могу воспроизвести в моей обертке возможность инициализировать std::array с рамно-Init-лист без ущерба для моей родовой обертки и я ntroducing решения, которые могут повредить совместимость обертки, например. std::vector?

ответ

-2

Пожалуйста, подтвердите свой ответ на вопрос this. Я считаю, что это дает довольно подробное объяснение того, что вы ищете.

3

Вместо использования:

SequenceContainerWrapper(initializer_list<value_type> init) : cont(init) {} 

вы можете использовать:

SequenceContainerWrapper(Container init) : cont(std::move(init)) {} 

Смотреть это работает на http://ideone.com/MzRQGC.

+0

спасибо. Но, из-за простого любопытства: если конструктор копирования - это все, что вам нужно, а также будет включать инициализацию списка инициализаторов, то почему 'std :: vector' предоставляет оба конструктора? http://en.cppreference.com/w/cpp/container/vector/vector У нас есть как вектор (const vector & other), так и 'vector (std :: initializer_list init);' там. Не будет 'vector (const vector & other),' достаточно? – gaazkam

+0

Мое мышление заключается в том, что с вашим отличным решением будет одна перегрузка конструктора из 'std :: vector', я не буду явно обертывать; поэтому, предполагая, что стандартная библиотека не предоставляет избыточные функции, должен быть по крайней мере один случай использования «std :: vector». Я не смогу покрыть ... – gaazkam

+1

@gaazkam, если 'std :: vector' did not предоставить 'vector (std :: initializer_list init)', вы не сможете использовать 'std :: initializer_list' для создания временного' std :: vector' в вызове для создания 'SequenceContainerWrapper'. –

Смежные вопросы