2011-10-05 114 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的答案中指出的那樣。