2011-10-05 1 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); 

しかしインターフェイスと同様に、配列の本体であることを知って、私が思うに、私たちが知っている必要はありませんよう(関数呼び出し前には一時変数は存在しません場合クラスクライアントのパラメータのタイプ)。だから、これを作る機会はありますか?

答えて

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に自動的に変換されています。

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

を..and同様のことは、構造体で行うことができます。

+0

実際、これはC++ 11の一様初期化のおかげで、*任意の*コンテナクラスで動作します。 –

20

C99では、これは動作します。

+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); 

単一行の初期化とベクトルサイズの指定が不要なため、この代償を払う代償があります。前のベクトルのコピーは、追加されるすべての要素に対して作成され、実行時間をベクトルサイズで少なくとも2次的にします。これは、短いベクトルやパフォーマンスが問題にならない場合に最適です。 spraffの答えで指摘されているように、C++ 11のためのより良い解決策があります。