Инициализируйте контейнер, который является закрытой переменной-членом класса

у меня есть list<string> myList как личный атрибут моего класса. Содержание этого списка известно во время компиляции и является постоянным. Есть ли какой-нибудь компактный способ (в C ++ 03) инициализировать его значение? Я могу думать только об этом:

MyClass::MyClass(){
myList.push_back(string("str1"));
myList.push_back(string("str2"));
myList.push_back(string("str3"));
etc.
}

Я хотел бы что-то вроде этого:

MyClass::MyClass():list("str1","str2","str3",etc.){
}

2

Решение

Этот код не полностью протестирован, но я бы посоветовал это, если вы не можете использовать новые и интересные вещи в C ++ 11:

class MyClassCreator
{
MyClass result;
public:
MyClassCreator(std::string param)
{
result.myList.push_back(param);
}

MyClassCreator& operator()(std::string param)
{
result.myList.push_back(param);
return *this;
}

operator MyClass() { return result; }

};

Использование:

MyClass c = MyClassCreator("object1")("object2")("object3");

РЕДАКТИРОВАТЬ

Смотрите полный пример на http://ideone.com/LWGRCc

3

Другие решения

Я склонен делать что-то вроде этого:

static const string my_strs[] =
{
"str1",
"str2",
"str3"};

static const num_my_strs = sizeof(my_strs)/sizeof(my_strs[0]);

Затем, когда приходит время инициализировать list:

MyClass::MyClass()
:  myList(my_strs, my_strs + num_my_strs)
{
}

…или же:

MyClass::MyClass()
{
copy( my_strs, my_strs+num_my_strs, back_inserter(myList));
}

У этого подхода есть свои плюсы и минусы. Очевидный недостаток — у вас есть 2 копии ваших данных. Это также поднимает вопрос, если вы знаете содержимое во время компиляции, и они никогда не меняются, вам даже нужно list совсем? Почему бы просто не использовать static const массив?

Что касается стороны профессионалов, код для инициализации списка является 1-строчным, и его не нужно менять, даже если вы измените постоянные данные времени компиляции, которые копируются в список.

Редактировать: Вы можете использовать стандартные библиотечные алгоритмы, такие как find с простыми старыми массивами в стиле C Например:

const string* it = std::find(my_strs, my_strs+num_my_strs, "str1");
if( it == (my_strs+num_my_strs) ) // functionally same as 'list.end()' eg, item not found
{
// not found
}
else
{
// found -- it points to item found
string found_item = *it;
}

Edit2 Является ли выражение как int a[2]; &a[2]; четко определено обсуждается. Я отредактировал указатель математики выше, чтобы использовать метод, который хорошо известен, чтобы не вызывать UB.

Edit3 Я нашел соответствующие отрывки в Стандарте, касающиеся этого. Вышеуказанное выражение (int a[2]; &a[2];) на самом деле неопределенное поведение. Я уже отредактировал свой ответ, чтобы не использовать этот метод. Спасибо @MooingDuck за это.

4

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector