vec
is a local variable. Its scope is limited to the GetArrayFromVector()
function only. Never return the address of a local variable. Either return the array by value:
std::vector<double> GetArrayFromVector( std::map<std::string, double> m,
char ** names, int count )
or, pass a reference to the vector as an output parameter:
void GetArrayFromVector( std::map<std::string, double> m,
char ** names, int count,
std::vector<double>& vec)
or, pass an output iterator:
void GetArrayFromVector( std::map<std::string, double> m,
char ** names, int count,
std::vector<double>::iterator vecIter)
The last two will require some careful implementation of the function definition and calling though.
Additionally, if you are game for a bit more adventure try this:
// you'd need to change the value to use when an element is not
// found in the map to something that suits your needs
double pred(std::map<char*, double> haystick, char* const needle) {
std::map<char*, double>::iterator i = haystick.find(needle);
return i != haystick.end() ? i->second : 0;
}
int main(int argc, char* argv[])
{
std::map<char *, double> m;
std::vector<char *> names;
std::vector<double> dv;
m[ "Sasha" ] = 729.0;
m[ "josh" ] = 8154.0;
names.push_back("Sasha");
names.push_back("JonSkeet");
names.push_back("josh");
// transform is part of STL's <algorithm> header
// it takes a container (actually a range -- [begin(), end())
// note it is a half-open range -----------^
// as is customary for all STL algorithms, applies the function
// or functor specified as the last parameter to each element of
// the sequence and writes the result back to another container
// specified via the output iterator -- the third argument
//
// since I have not reserved enough elements for the vector dv
// i cannot blindly use it -- i need a back_inserter to coax
// transform to push_back() instead of do an insert operation
// of course, for vectors, this is costly since reallocations
// may happen, but let's leave the performance aside for a while!
//
// ok, so what about the last parameter, you ask? it has to be an
// unary_operation. well, mostly so. but what is it that we want?
// we want to take an iterator from the original char* (string)
// array and see if there's an entry in the map. if there is one
// we retrieve the associated double value and put it in dv; else,
// we set a default value of 0 -- change it to whatever pleases you
// maybe a std::numeric_limit<double> if it works for you.
//
// you can create a functor inheriting std::unary_function and pass
// it on. that's the easy way out. but what if you already have a
// comparator, a C-style find() function? will it work? yes, it will.
// but we have to wrap it using the function adaptor std::ptr_fun
// to make the compiler happy (after all it wants a unary_function, right?)
//
// this simple scheme of things works very well, save for a last little
// glitch. the comparator actually takes two parameters -- a what to search
// and a where to search. and guess what -- the where to search is always
// fixed. so that gives us a good oppertunity to fix the first parameter to
// our map<char*, double> which is exactly what std::bind1st() does.
// surprisingly, now that you've fixed one function, you no longer have a
// binary function (one taking two arguments) but an unary one -- which is
// just what you'd pass to transform. voila!
std::transform(names.begin(), names.end(), std::back_inserter(dv),
std::bind1st(std::ptr_fun(pred), m));
std::copy(dv.begin(), dv.end(),
std::ostream_iterator<double>(std::cout, "\n"));
return 0;
}
Some interesting links:
Also check out Boost. They have done some magic with bind()
!