Итак, я хочу расширить существующий векторный класс в моей программе, чтобы я мог сказать это,
vector<string>* vec = new vector<string>(){"Value1","Value2"};
или же
vector<string>* vec = new vector<string>({"Value1","Value2"});
или же
vector<string> vec = {"Value1","Value2"};
Я знаю, что могу сделать что-то подобное, но сделав это,
string temp[] = {"Value1","Value2"};
vector<string> vec(temp, temp+ sizeof(temp) / sizeof( temp[0] ) );
Это использует конструктор итератора векторов, но я не могу удалить лишнюю строку?
Я знаю, что в C # вы можете добавить все, что хотите, к существующим вещам, используя partial
ключевое слово как это,
public partial class ClassName
{
ClassName(Stuff stuff)
{
}
void AmazingNewMethod()
{
}
}
Есть ли в C ++ отличный трюк где-то вроде этого?
Должен ли я наследовать вектор и построить customVector
у этого есть конструктор, который за кулисами делает конструктор итератора?
Может быть, обернуть эти строки в статический вызов функции-помощника, который устанавливает его по ссылке и добавить его где-нибудь в класс инструментов?
Я чувствую, что многие программисты решили эту проблему. Есть ли какие-нибудь элегантные решения там?
Благодарю.
Редактировать: исправил заголовок, чтобы упомянуть, что это конструктор списка инициализатора.
В C ++ 11 было бы initializer lists
чтобы приспособить этот подход. Поскольку вы упоминаете .NET, я теперь предполагаю, что вы используете MS Visual Studio. Microsoft делает НЕ реализовать списки инициализаторов, поэтому самый простой способ сделать что-то подобное — это функция, которая возвращает вектор со всеми добавленными элементами.
На partial
вещь: C ++ не предлагает возможности в том же духе, что и частичные классы .NET.
C ++ 2011 — это принять std::initializer_list<T>
в качестве аргумента конструктора:
#include <initializer_list>
template <typename T>
class foo {
T *d_array;
public:
foo(std::initializer_list<T> list)
: d_array(new T[list.size()]) {
std::copy(list.begin(), list.end(), this->d_array);
}
foo(foo const&);
foo& operator= (foo const&);
~foo() { delete[] this->d_array; }
};
Вышесказанное явно концентрируется только на том, как использовать std::initializer_list<T>
, Чтобы на самом деле сделать выделение внутри, вы должны выделить необработанную память и создать объект на месте. Однако вопрос был не в этом.
Что касается добавления этой поддержки в std::vector<T>
: тебе не нужно! В C ++ 2011 std::vector<T>
может быть инициализирован с std::initializer_list<T>
, В C ++ 2003 вы не можете сделать это. Лучшее, что вы можете сделать, — это поддерживать конструкцию из массива, используя конструктор, который выглядит примерно так:
template <typename T>
template <typename S, int Size>
foo<T>::foo(S const (&array)[Size])
d_array(new T[Size]) {
std::copy(array, array + Size, d_array);
};
Однако нет возможности расширить существующее без изменения его типа. Чтобы избежать переопределения большинства членов, вы можете публично наследовать от типа, который вы хотите расширить, и добавить все необходимые конструкторы (они не наследуются; в C ++ 2011 вы могли бы наследовать существующие конструкторы, но тогда, в C ++ 2011 вам не нужно было бы все равно делай это).
Альтернатива, которую вы, возможно, захотите использовать с C ++ 2003, заключается в создании факторной функции, использующей встроенный массив, то есть что-то вроде этого:
template <typename T, typename S, int Size>
std::vector<T>
make_vector(S const (&array)[Size]) {
return std::vector<T>(array, array + Size);
}
char const* init[] = { "Hello", "World" };
std::vector<std::string> value = make_vector<std::string>(init);