2

我有一个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.){
}
4

2 回答 2

4

我倾向于做这样的事情:

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-liner,即使您更改正在处理到列表中的编译时常量数据,也永远不需要更改。

编辑: 您可以使用标准库算法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];) 实际上是 Undefined Behavior。我已经编辑了我的答案以不使用该方法。感谢@MooingDuck 提出这个问题。

于 2012-11-07T17:32:44.433 回答
3

这段代码没有经过全面测试,但如果你不能在 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上的完整示例

于 2012-11-07T17:30:49.040 回答