views:

56

answers:

4

For example:

int main()
{
    {
        // I want this array to be part of the inner scope
        string s[] = {"Ben","Joe","Bob","Matt"};

        // And I want to use it to initialize this vector, but I want this
        // vector to be visible in the outer scope
        vector<string> names(s,s+4);
    }
}

Is there any way to do that?

+3  A: 

If you want the vector to be visible in the outer scope, you must declare it in the outer scope. Which means that you also have to initialize it there. The only way to declare it without initializing is by using a pointer:

int main()
{
  vector<string> * names = 0;

  {
    string s[] = {"Ben", "Joe", "Bob", "Matt"};
    names = new vector<string>(s, s+4);
  }

  // ...
  delete names;
}
ldx
Your use of pointers gave me a good idea.
PigBen
A: 

ldx's mentioning of pointers gave me an idea. I've never used shared_ptr before, but I thought it might be the solution, so I looked them up, and I came up with this solution:

Edit: changed to auto_ptr

int main()
{
    auto_ptr<vector<string> > vsptr;

    {
        string s[] = {"Ben", "Joe", "Bob", "Matt"};
        int cnt = sizeof(s)/sizeof(string);

        vsptr = auto_ptr<vector<string> >(new vector<string>(s,s+cnt));
    }

    vector<string> &names = *vsptr;
}

I tested it with a class that announces it's constructors, assignments and destructors, and there's only one default construction and one destruction. Of course, this requires boost if your compiler doesn't implement tr1 yet, but what compiler worth a damn doesn't?

PigBen
std::auto_ptr would be fine in this case; you don't share the pointer anywhere.
Pete Kirkham
Yep, you're right. Turns out I'd never used auto_ptr either.
PigBen
A fine idea indeed, but you'll have to be careful: If vsptr goes out of scope before names does, then names will become invalid
ldx
A: 

Although not strictly initialising the vector, if you want your object to be auto rather than dynamically allocated you can swap it with a temporary:

{
    vector<string> names;

    {
        string s[] = {"Ben","Joe","Bob","Matt"};

        vector<string> init (s,s+4)

        swap ( names, init );
    }
}

Though you still get the major copies going on ( the char* literals copied to construct the std::strings in the array, then the std::strings in the array copied to the vector ) the swap avoids the copy of the strings from init to names.

Pete Kirkham
+1  A: 
int main()
{
    vector<string> names;
    {       
        string s[] = {"Ben","Joe","Bob","Matt"};
        names.assign(s,s+4);
    }
}
Armen Tsirunyan