у меня есть 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.){
}
Этот код не полностью протестирован, но я бы посоветовал это, если вы не можете использовать новые и интересные вещи в 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
Я склонен делать что-то вроде этого:
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 за это.