2011-10-05 119 views
17

我正在寻找在接下来的局面有所帮助:
我有一些类,并在它的一些方法,语法是这样的:数组的初始化体作为函数参数(C数组),可以吗?

class SomeClass { 
    public: 
      void doSomething(int *a); 
}; 

所以我想调用这个方法就像

SomeClass::doSomething({ 0, 1, 2, 3, 4 }); 

在任何语言中都可以吗? 欢迎任何(C++,C,obj-c,obj-C++)实现! 我知道这个初始化块阵列的身上,就像

int *a = { 0, 1, 2, 3, 4 }; 
SomeClass::doSomething(a); 

但界面会很好看,我认为,如果有会前函数调用任何临时变量(因为我们并不需要知道class-client中的参数类型)。那么,有没有机会做到这一点?

回答

8

这是关于C++ 11 initializer lists(部分18.9)。

void foo (std :: initializer_list <int> inputs) { 
    for (auto i : inputs) { 
     // ... 
    } 
} 

foo ({10, 20, 30}); 

只有编译器可以创建一个初始化列表,但您可以用begin()end()size(),和随机访问迭代器把它像一个标准的STL风格的容器。

std::vector(我希望一些其它容器)现在可以使用初始化列表构造,所以

std :: vector <std :: string> foo {"a", "b"}; 

相当于

std :: vector <std :: string> foo; 
foo .push_back ("a"); 
foo .push_back ("b"); 

不同之处在于它可以执行较少的分配。请注意,const char*已被自动转换为std::string

+0

事实上,这将与*任何*容器类一起工作,这要归功于C++ 11的统一初始化。 –

20

在C99这个工程:

functionThatTakesIntPtrOrArray((int []){ 1, 2, 3, 4 }); 

..和类似的事情可以用结构来完成。

+0

非常感谢,救了我很多耐心! –

+2

很遗憾,在C++中不起作用。您会收到错误“正在接收临时阵列的地址”。 – Timmmm

+0

不适用于Visual Studio 2017(v141) – sergiol

2

如果initializer_list不可用,和阵列大多是小,还有另一种选择,超载<<运营商的std ::矢量这样的:

template <typename T> 
inline std::vector<T> operator <<(const std::vector<T>& vec, const T& val) { 
    std::vector<T> result(vec); 
    result.push_back(val); 
    return result; 
} 

有了这一点,你可以这样做:

void foo (const std::vector<int>& inputs) { 
    // ... 
} 

foo (std::vector<int>() << 10 << 20 << 30); 

单线初始化的这种便利性并不需要指定矢量大小。为每个添加的元素创建一个先前矢量的副本,使得矢量大小的运行时间至少为二次方 - 这就是为什么当性能无关紧要时,它最适合短矢量和情况。对于C++ 11来说,有更好的解决方案,正如在spraff的答案中指出的那样。