2011-08-26 170 views
1

我有一个包含一个向量类:将可变大小元素列表添加到向量的语法糖?

class Foo { 
    typdef std::vector<int> Vec; 
    Vec m_kids; 
    void addKids(Vec::const_iterator begin, 
       Vec::const_iterator end) { 
    m_kids.insert(m_kids.end(), begin, end); 
    } 
}; 

有没有什么办法可以让下面简洁的函数调用? (也许通过改变上述addKids功能?)

int main() { 
    Foo foo; 
    foo.addKids(23,51,681);    // these... 
    foo.addKids(3,6,1,4,88,2,4,-2,101); // ...would be nice?! 
} 

我怀疑你可以用的C++ 0x矢量初始化列表办呢?但不幸的是,我不能使用C++ 0x。如果有帮助,我可以使用Boost。

回答

5

你可以这样做:

Foo foo; 
foo << 3, 6, 1, 4, 88, 2, 4, -2, 101; //inserts all! 

,为您所超载<<,运营商,如:

class Foo { 
    typdef std::vector<int> Vec; 
    Vec m_kids; 
public: 
    Foo& operator<<(int item) { 
    m_kids.push_back(item); return *this; 
    } 
    Foo& operator,(int item) { 
    m_kids.push_back(item); return *this; 
    } 
}; 

一旦你实施这个,那么你也可以写:

foo << 3 << 6 << 1 << 4 << 88 << 2 << 4 << -2 << 101; //inserts all! 

即使这样,

foo, 3, 6, 1, 4, 88, 2, 4, -2, 101; //inserts all! 

或者混合使用这两个为:

foo << 3, 6, 1 << 4, 88, 2 << 4 << -2, 101; //inserts all! 

//and this too! 
foo,3 << 6, 1 << 4, 88, 2 << 4 << -2, 101; //inserts all! 

全部都是一样的!

但混合看起来不太好。我的首选是第一个!

+1

这很聪明!重载'operator,'只是为了与我想要的语法兼容?正如你写的那样,'foo << 3 << 6 ...'会起作用,对吧? – carlpett

+0

@carlpett:是的。 – Nawaz

+0

+1这是'boost :: assign'库中的一种方法,我不喜欢它,但仅仅是品味问题(它是我不喜欢的'operator'的重载)。或者,C++的CORBA映射为'类似的目的使用'operator = <<'的重载,就像'<<'一样丑陋(如果不是更多),但不太可能与插入到流中混淆。 –

0

,我不知道有任何升压功能,做到这一点(最有可能的,只是因为我还没有看到它,“助推了它“几乎是一个axoim ...),但是你可以定义一个可变参数来实现它。它会是这个样子:

void addKids(int N, ...) { 
    va_list args; 
    va_start(args, N); 
    for(int i = 0; i < N; ++i) { 
     int val = va_arg(args, int); 
     m_kids.push_back(val); 
    } 
    va_end(args); 
} 
+1

只是一句话,语法将不完全相同,因为'N'是元素的数量。因此,对于您的示例,它将是'foo.addKids(3,23,51681);'和'foo.addKids(9,3,6,1,4,88,2,4,-2,101);' – carlpett

+0

虽然我知道可变参数并不完美,现代的C++,它_does_工作... -1没有犹太教? – carlpett

+0

这种方法的另一个限制是C++ 03中的变量参数只能用于基本类型(并且只能使用它们的一个子集,IIRC) –

0

如果你改变你的迭代器类型

template<typename T> 
void addKids(T begin, T end) 
{ 
    m_kids.insert(m_kids.end(), begin, end); 
} 

,那么你至少可以做到这一点:

int kids={1,2,3,4}; 
foo.addKids(kids,kids+4); 

这似乎很简洁。