web-dev-qa-db-fra.com

Initialisation du tableau de chaînes c ++

Je sais que je peux le faire en C++:

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

Mais existe-t-il de toute façon de supprimer un tableau de cette façon sans supprimer string s[]?

par exemple.

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

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

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

En C++ 11, vous pouvez. Une note à l'avance: Ne pas new le tableau, cela n'est pas nécessaire.

Première, string[] strArray est une erreur de syntaxe, qui doit être soit string* strArray ou string strArray[]. Et je suppose que c'est juste à titre d'exemple que vous ne passez aucun paramètre de taille.

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

Notez qu'il serait préférable que vous n'ayez pas besoin de passer la taille du tableau comme paramètre supplémentaire, et heureusement, il existe un moyen: les modèles!

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

Notez que cela ne correspondra qu'aux tableaux de pile, comme int x[5] = .... Ou temporaires, créés par l'utilisation de alias ci-dessus.

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

Avant C++ 11, vous ne pouvez pas initialiser un tableau à l'aide du type []. Cependant, le dernier c ++ 11 fournit (unifie) l'initialisation, vous pouvez donc le faire de cette manière:

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

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

9
Guangchun

Avec la prise en charge des listes d'initialisation C++ 11, c'est très simple:

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

Sans cela (par exemple pour Visual C++ 10.0), vous pouvez faire des choses comme ceci:

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

En C++ 11 et supérieur, vous pouvez également initialiser std::vector avec une liste d'initialisation. Par exemple:

using namespace std; // for example only

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

Ainsi, votre exemple deviendrait:

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

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

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