2017-02-07 5 views
1

У меня есть некоторый код, который эффективно снижает доИзменение списка инициализации членов

#include <vector> 
class A { 
    std::vector<int> m_sizes; 
public: 
    A(std::initializer_list<int> const& sizes) : m_sizes(sizes) {} 
}; 

class B { 
    A m_a; 
public: 
    B(int size_front, int size_back, std::initializer_list<int> const& sizes) : m_a({ size_front, sizes, size_back }) {} 
}; 

Компилятор жалуется, что ни один экземпляр A::A не совпадает со списком аргументов. Есть ли способ сгладить { int, std::initializer_list<int>, int } до std::initializer_list<int> или мне нужно дать A дополнительный конструктор для обработки этой ситуации? Что делать, если я не могу изменить класс A?

+2

'станд :: initializer_list' не изменяемые. Этот шаблон в основном предназначен для использования компилятором. Единственный способ инициализировать новый 'std :: initializer_list' - это конструктор по умолчанию, создающий пустой список или скопированную константу. В этом случае 'A' нуждается в другом конструкторе, который принимает параметр' vector', и использует это для инициализации 'm_sizes'; то вы можете использовать этот конструктор. Если вы не можете изменить класс 'A', ничего не может быть сделано. C++ не работает. –

ответ

2

То, что вы пытаетесь сделать, невозможно: initializer_list<T> должен быть построен из списка элементов типа T, чей счет известен во время компиляции. Вставка существующего списка в середине не работает.

Вы можете обойти эту проблему, добавив перегрузки конструктора, который принимает vector<int> непосредственно, и переадресации вызовов к нему:

class A { 
    std::vector<int> m_sizes; 
public: 
    A(const std::vector<int>& sizes) : m_sizes(sizes) {} 
    A(std::initializer_list<int> const& sizes) : A(std::vector(sizes)) {} 
}; 
class B { 
    A m_a; 
    std::vector<int> frame(int size_front, int size_back, std::initializer_list<int> const& sizes) { 
     std::vector res; 
     res.push_back(size_front); 
     std::copy(sizes.begin(), sizes.end(), std::back_inserter(res)); 
     res.push_back(size_back); 
     return res; 
    } 
public: 
    B(int size_front, int size_back, std::initializer_list<int> const& sizes) : m_a(frame(size_front, size_back, sizes)) {} 
}; 
+0

Хммм .... Я чувствую ошибку копирования-пасты? .... Проверьте порядок типов параметров в функции-члене 'B :: frame()' и то, что вы передали в * member-initialization-list * в конструкторе 'B' – WhiZTiM

+0

@WhiZTiM Вы абсолютно правы, спасибо вам большое! – dasblinkenlight