Инициализация строкового массива С++
Я знаю, что могу сделать это на С++:
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
Ответы
Ответ 1
В С++ 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});
}
Ответ 2
До С++ 11 вы не можете инициализировать массив, используя тип []. Однако последний С++ 11 обеспечивает (унифицирует) инициализацию, поэтому вы можете сделать это следующим образом:
string* pStr = new string[3] { "hi", "there"};
См. http://www2.research.att.com/~bs/C++0xFAQ.html#uniform-init
Ответ 3
С поддержкой списков инициализаторов С++ 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 С++ 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" );
}