инициализация массива строк c ++ - PullRequest
20 голосов
/ 09 марта 2012

Я знаю, что могу сделать это в C ++:

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

Но есть ли способ удалить массив таким образом, не разделив string s[]?

, например

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

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

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

Ответы [ 4 ]

18 голосов
/ 09 марта 2012

В 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});
}
9 голосов
/ 09 марта 2012

До C ++ 11 вы не можете инициализировать массив, используя тип []. Однако последняя версия C ++ 11 обеспечивает (объединяет) инициализацию, поэтому вы можете сделать это следующим образом:

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

См. http://www2.research.att.com/~bs/C++0xFAQ.html#uniform-init

4 голосов
/ 09 марта 2012

С поддержкой списков инициализаторов C ++ 11 это очень просто:

#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" } ); 
}

Не имея этого (например, для Visual C ++ 10.0), вы можете делать такие вещи:

#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" ); 
}
0 голосов
/ 19 марта 2019

В C ++ 11 и выше вы также можете инициализировать std::vector списком инициализаторов.Например:

using namespace std; // for example only

for (auto s : vector<string>{"one","two","three"} ) 
    cout << s << endl;

Итак, ваш пример будет:

void foo(vector<string> strArray){
  // some code
}

vector<string> s {"hi", "there"}; // Works
foo(s); // Works

foo(vector<string> {"hi", "there"}); // also works
...