2012-03-08 24 views
18

私はC++でこれを行うことができます知っている:C++文字列配列の初期化

string s[] = {"hi", "there"}; 

しかしstring s[]をdelcaringせずに配列をこのようにdelcareするとにかくはありますか?

void foo(string[] strArray){ 
    // some code 
} 

string s[] = {"hi", "there"}; // Works 
foo(s); // Works 

foo(new string[]{"hi", "there"}); // Doesn't work 
+3

なぜ動的に割り当てられたCスタイルの配列を使用しますか?代わりに 'std :: vector'を使うことをお勧めします。 C++ 11を使用する場合、初期化リストを使用してそれらを構築することができます。 'void foo(vector ); – Grizzly

答えて

18

C++ 11で可能です。あらかじめメモ:newの配列はありません。その必要はありません。

まず、string[] strArrayは構文エラーです。string* strArrayまたはstring strArray[]のいずれかです。そして、私はあなたがどんなサイズのパラメータも渡さないという例のためだけだと仮定します。テンプレート:あなたは余分なパラメータとして配列のサイズを渡す必要はありませんでした場合、それが良いだろう、とありがたいな方法があることを

#include <string> 

void foo(std::string* strArray, unsigned size){ 
    // do stuff... 
} 

template<class T> 
using alias = T; 

int main(){ 
    foo(alias<std::string[]>{"hi", "there"}, 2); 
} 

注意!

template<unsigned N> 
void foo(int const (&arr)[N]){ 
    // ... 
} 

これは、int x[5] = ...のようなスタック配列にのみ一致することに注意してください。または上記のaliasの使用によって作成された一時的なもの。

int main(){ 
    foo(alias<int[]>{1, 2, 3}); 
} 
8

C++ 11以前では、[]型を使用して配列を初期化することはできません。あなたはこの方法でそれを行うことができますので、しかし、最新のC++ 11には、(を統一)初期化を提供します。

string* pStr = new string[3] { "hi", "there"}; 

は、それは非常に簡単であるC++ 11の初期化子リストのサポートによりhttp://www2.research.att.com/~bs/C++0xFAQ.html#uniform-init

4

を参照してください。

あなたはこのようなことを行うことができます(例:ビジュアルC++ 10.0用)という欠け
#include <iostream> 
#include <vector> 
#include <string> 
using namespace std; 

using Strings = vector<string>; 

void foo(Strings const& strings) 
{ 
    for(string const& s : strings) { cout << s << endl; } 
} 

auto main() -> int 
{ 
    foo(Strings{ "hi", "there" }); 
} 

#include <iostream> 
#include <vector> 
#include <string> 
using namespace std; 

typedef vector<string> Strings; 

void foo(Strings const& strings) 
{ 
    for(auto it = begin(strings); it != end(strings); ++it) 
    { 
     cout << *it << endl; 
    } 
} 

template< class Elem > 
vector<Elem>& r(vector<Elem>&& o) { return o; } 

template< class Elem, class Arg > 
vector<Elem>& operator<<(vector<Elem>& v, Arg const& a) 
{ 
    v.push_back(a); 
    return v; 
} 

int main() 
{ 
    foo(r(Strings()) << "hi" << "there"); 
} 
+1

あまりにも冗長すぎる:範囲ベースのループを使います: 'for(auto s:strings)cout << s << endl;' foo({"hi"、 "there"}) – rwst

+0

@rwst:はい、今日です。ありがとう。私はおそらく、2012年に一般的なVisual C++をサポートするために反復子を使用していました。あなたが示すシンプルなループは、文字列をコピーしますが、(1)ループ本体のioに比べて重要ではなく、(2) (3)効率のための書き換え(悪い熟語を教えることではない)を理解することは難しくありません。ですから、2015年に私が使用したイテレーターループを維持する理由はありません。自由に修正してください。 :) –

+0

@rwst:OK私はそれを自分で更新しました。 Visual C++ 10の例がVC10で実際にコンパイルされていることも確認しました。私は今それを見てVC10がrvalue参照をサポートしていることを覚えていませんでしたが、(少なくともコードはコンパイルして正しい結果を出します) –