2016-02-12 2 views
0

Я пытаюсь создать шаблон класса, где его конструктор имеет конструктор Variadic, и каждый тип параметра должен быть одним и тем же типом данных. Я хотел бы сохранить все параметры в контейнер std::vector< std::shared_ptr<T> >. Если параметры не переданы, то самое первое shared_ptr<> в vector<> будет установлено и сохранено как nullptr. Также я хотел бы иметь возможность отслеживать, сколько параметров передано. Пока это то, что я пробовал.Шаблон класса с вариационным конструктором; сохранение параметров в std :: vector <std :: shared_ptr <>>

декларация

template<typename T> 
class Nodes { 
private: 
    unsigned m_numParams; 
    std::vector<sstd::shared_ptr<T>> m_vNodes; 

public: 
    explicit Nodes(T...); // Not sure how to set first parameter as being default to nullptr along with the variadic syntax. 

}; 

определение

template<typename T> 
Nodes<T>::Nodes(T...) { 

    if (/* no parameters passed in or 1st parameter is nullptr */) { 
     T* ptr = nullptr; 
     m_vNodes.push_back(ptr); 
    } else { 
     for each (/* parameter with same data type */) { 
      std::shared_ptr<T> sptr(new T()); 
      m_vNodes.push_back(sptr); 
     } 
    } 
    m_numParams = m_vNodes.size(); 
} 

Мое понимание основных шаблонов является достойным, но мое использование функций или переменного числа шаблонов ограничены, и я пытаюсь узнать новым методы для дальнейшего улучшения моего общего навыка, установленного на языке C++. Я хотел бы знать, является ли мой первоначальный подход логически правильным путем; если эта концепция будет достигнута, и если да, то какой будет наиболее эффективный способ ее реализации, поэтому, когда я использую этот шаблон класса, это то, чего я ожидал бы и действительно имел бы место, как в этом примере ниже:

#include "SomeHeader.h" 

int main() { 

    int x = 3; 
    int y = 5; 
    int z = 7; 

    Nodes<int> someNodes(x, y, z); 

    return 0; 
} 

внутренние узлы приватная переменная-член будет иметь shared_ptr<int> где

Nodes::m_vNodes[0] = address of x with value 3 stored 
Nodes::m_vNodes[1] = address of y with value 5 stored 
Nodes::m_vNodes[2] = address of z with value 7 stored 

и если параметры не передаются, как в ...

#include "SomeHeader.h" 

int main() { 

    Nodes<int> someNodes(); 

    return 0; 
} 

внутренняя переменная-член должна иметь «nullptr», хранящуюся в местоположении [0]. Должен ли я также реализовать его конструктор по умолчанию Nodes(); Или это достижимо все от одного конструктора?

Как только я правильно работаю над этим конструктором, у меня не возникнет проблем с переходом вперед, чтобы написать функции или методы для добавления, удаления, извлечения, хранения, упорядочивания или сортировки данных, сравнения данных или управления данными. Я искал здесь и там и, похоже, не нашел ничего подходящего для того, что я ищу. Любые советы, советы, помощь, ссылки или примеры будут по-настоящему оценены, и я любезно благодарю вас заранее.

+3

Это звучит, как вы, возможно, хотите [ 'std :: initializer_list'] (http://en.cppreference.com/w/cpp/utility/initializer_list) – NathanOliver

+0

@NathanOliver Я поддержал вашу компанию как я люблю и ценю предложение или подсказку. Однако я пытался понять, как это можно сделать так, как я изначально спросил. Я стараюсь изо всех сил изучать вариационные функции/вариационные шаблоны и т. Д. –

ответ

3

initializer_list кажется лучшим выбором, но с VARIADIC шаблон, это должно быть что-то вроде:

template<typename T> 
class Nodes { 
private: 
    unsigned m_numParams; 
    std::vector<std::shared_ptr<T>> m_vNodes; 

public: 
    Nodes() : m_numParams(0), m_vNodes{nullptr} {} 

    template <typename ... Ts> 
    explicit Nodes(Ts&&...ts) : 
     m_numParams(sizeof...(Ts)), 
     m_vNodes{std::make_shared<T>(std::forward<Ts>(ts))...} 
    {} 
}; 

с initializer_list:

explicit Nodes(std::initializer_list<T> ini) : 
    m_numParams(ini.size()) 
{ 
    for (auto&& e : ini) { 
     m_vNodes.push_back(std::make_shared<T>(e)); 
    } 
} 

Demo

+0

Благодарим вас за своевременный ответ; он работает надлежащим образом. Синтаксис для меня новичок, и я еще не использовал make_shared <> (forward <>()), поэтому это отличная помощь, а не просто для того, чтобы это работало, но помогло понять, как писать variadic fuctions/templates. Это красиво, чисто и компактно.Причина, по которой я хочу эту структуру в отличие от списка инициализаторов, заключается в том, что я использую эти элементы для хранения в качестве общего указателя в векторе. Теперь, если это можно сделать в другом подходе с помощью std :: initializer_list; то я также открыт для альтернатив. –

+0

Когда я пытаюсь использовать конструктор 'std :: initialize_list' конструктора в файле myain.cpp, где я передаю целочисленные переменные x, y, z в конструктор узлов, он не компилируется для меня; Я не уверен, как использовать эту версию в своем приложении; вы могли бы показать мне пример? –

+0

После выполнения проб и ошибок в моем main.cpp я, наконец, получил версию 'std :: initializer_list' для работы. Мне пришлось создать его экземпляр как таковой: 'std :: initializer_list ini {x, y, z};' и передать его в конструктор 'Nodes'. –

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