how to save this vector - c++

I want to know how I can define vector variables to save output of this code in vector?
/*what should be here?*/=agent.GetInfoState().GetPositionInfo().GetCloseTeammateToTeammate(2);
GetcloseTeammateToTeammate is defined as:
const std::vector<Unum> & GetCloseTeammateToTeammate(Unum i)
{
Assert(i > 0); return GetCloseTeammateToPlayer(i); }

GetCloseTeammateToTeammate returns a reference to a constant vector.
Simply use:
const std::vector<Unum>& x = agent.GetInfoState().GetPositionInfo().GetCloseTeammateToTeammate(2);
to get the reference. Note that you can only call const member functions of vector.
To get a copy of the vector, do:
std::vector<Unum> x = agent.GetInfoState().GetPositionInfo().GetCloseTeammateToTeammate(2);
Only copy if you really need to.

I must be missing something here. Is it not simply this:
const std::vector<Unum> &my_vector = agent.GetInfoState().GetPositionInfo().GetCloseTeammateToTeammate(2);

There are two different options there, depending on what you actually want. If you only intend to do some processing on the given vector in the short term, (and assuming single threaded execution and a couple other considerations) you can just keep the reference:
std::vector<Unum> const & v = agent.GetInfoState().GetPositionInfo().GetCloseTeammateToTeammate(2);
for ( std::vector<Unum>::const_iterator it = v.begin(), end = v.end(); it != end; ++it )
{
// do something
}
If what you want is to save a copy of the vector so that at a later time you can check for changes, or you want to use the vector as it is now without any later changes (note that this is not entailing thread safety!), just copy it:
std::vector<Unum> copy = agent.GetInfoState().GetPositionInfo().GetCloseTeammateToTeammate(2);

Related

Return two vectors – use reference or tuple?

What is better to use for return two initialized vectors? I remember that few years ago was better to use passing a reference and change it inside function to avoid copy a value but I'm not sure how it is nowadays in C++17 and a copy elision.
Example:
void sample1(vector<string>& v1, vector<string>& v2) {
for (auto i = 0; i < 1000000; ++i) {
v1.push_back(random_string(10));
v2.push_back(random_string(10));
}
}
tuple<vector<string>, vector<string>> sample2() {
vector<string> v1, v2;
for (auto i = 0; i < 1000000; ++i) {
v1.push_back(random_string(10));
v2.push_back(random_string(10));
}
return { std::move(v1), std::move(v2) };
}
int main() {
{
std::vector<std::string> v1, v2;
sample1(v1, v2);
}
{
auto [v1, v2] = sample2();
}
}
Is there any difference in a performance between sample1 and sample2? I measured and both takes around 16 seconds on my machine so I suppose there is no difference because the copy constructor is not called in second example. If I remove std::move, then sample2 is slower by ca. 3 seconds
There's no universal answer.
Returning is more convenient. You don't have to think about previous content, you have less lines of code on caller side. It is more idiomatic, after all.
But if the function would be called in a loop, then reference version allows memory to be reserved just once, not on each function call (by using the same vectors as output).
I recommend to use std::pair for returning two vectors. I think the common programming style is to pass input parameters by const reference and for outputs use function return value, e.g. something like this:
outputs = f(input params)
With this style, it is much easier to find out input parameters and the output value of every function from its declaration. In addition, standard library uses this style when it needs to have two outputs for a function. One example is the std::set::insert:
std::pair<iterator,bool> insert( const value_type& value )

Vector of pointers and erasing a specific value

I am having a little bit of trouble with finding a way to erase a value from a vector of pointer.
I have a vector std::vect<MyClass*> myVect which contains pointers to objects o1, o2,... in a specific order. I am having a bit of trouble to find how to delete the entry of one specific object, for example o1
I tried
void remove(MyClass C)
{
myVect.erase( std::find_if( myVect.begin(), myVect.end(), [&](MyClass* W)
{return &C == W;} ) );
}
but my bool lambda never returns true (verified with assert) . Is there something I am doing wrong? (I must say that I am not really familiar with Lambda functions/tors)
Thank you very much!
Your function accepts a MyClass by value as C, so it's always working with a freshly made instance in the function's local scope.
Your test function is checking &C == W;, but it's impossible for the address of C to match the address stored in the vector (unless remove added it earlier).
If you really want the test to be by address, you probably want to accept your argument by reference, void remove(MyClass& C) in which case some other part of your code could pass an existing object by reference whose pointer might be in the vector.
More likely, you want the test to be by value, in which case, for efficiency, you probably want code more like this:
void remove(const MyClass& C) // Receive by const reference to avoid pointless copy
{
// Testing C == *W tests the value pointed to, not the pointers themselves
myVect.erase( std::find_if( myVect.begin(), myVect.end(), [&](MyClass* W)
{return C == *W;} ) );
}

Passing output of c++ transform to a function

I'm sorry if this is a stupid question but I'm a bit of a c++ noob and I haven't been able to find the answer. I'm working with boost multi_array, and I'm trying to do something like this:
typedef boost::multi_array<double,2> array2D;
typedef array2D::array_view<1>::type array2Drow;
typedef boost::multi_array_types::index_range range;
...
array2D A = ... (2-d array) ...;
array2Drow X = A(boost::indices[0][range()]);
...
returnVal1 = f(X);
returnVal2 = f(X+0.1*X);
returnVal3 = f(X-0.1*X);
I was trying to use std::transform for this; I understand I can write some sort of functor (call it "op") that multiplies X by 0.1 and adds/subtracts the result from X, but this is where I run into trouble--I don't know what to put in place of the ???:
returnVal1 = f(X);
returnVal2 = f(transform(X.begin(),X.end(),???,op(0.1,X)));
returnVal3 = f(transform(X.begin(),X.end(),???,op(-0.1,X)));
Is there a way to do this without defining an intermediate object that then gets passed to f? Thanks in advance!
If your function f takes a container, then you will have to create a container with the transformed values. In your example you seem to also expect that X remains unchanged by the first transformation, so you you cannot just modify it inplace
returnVal1 = f( X );
transform( X.begin(), X.end(), X.begin(),
[]( double val ){ return val + 0.1*val; } );
returnVal2 = f( X );
If you don't want to create explicit local temporaries then you can construct them using a helper function.
// pass in by value to get a copy, modify it inplace and return it
array2Drow transformed( array2Drow copy, double factor )
{
std::transform( copy.begin(), copy.end(), copy.begin(),
[&]( double val ){ return val + factor*val; } ) );
return copy;
}
The calculation of the return values can then be written using the helper.
returnVal1 = f( X );
returnVal2 = f( transformed( X, 0.1 ) );
returnVal3 = f( transformed( X, -0.1 ) );
The ??? needs to be an iterator for a container where you want to store the result of the transform operation, i.e. the return value of op
However, your idea is wrong.
std::transform returns (see http://en.cppreference.com/w/cpp/algorithm/transform)
Return value
Output iterator to the element past the last element transformed.
It makes no sense to pass that iterator to a function as it is end of the container.
Further, the signature of op doesn't fulfil the requirements for std::transform.
If f expects to receive a array2Drow, then you need to pass it one (containing the correct data).
With that given, you really only have a couple of choices: either modify the data in the existing collection (and repeatedly pass the same collection), or else create a new collection each time you invoke it.
If f really only needs one of the items at a time (e.g., like an accumulator), then you may be able to rewrite f to only take one input at a time, then at the end of each "run", retrieve the value and reset the accumulator.
In that case, you can probably create an iterator type that will invoke the accumulator for each item as its created, and pass an instance of that accumulator to std::transform as the destination where the result should be written.
For reference, you may want to look at Boost Accumulators.

Avoid constructing a new object if it is a parameter and could be modified instead

I have some code like this, where vec is some kind of vector-class:
Vec Vec::choose(const Vec& ifPositive, const Vec& ifNegative) const {
Vec out(mSize);
for(int index = 0; index < mSize; ++index) {
if(mData[i] > 0)
out[i] = ifPositive[i];
else
out[i] = ifNegative[i];
}
return out;
}
Now this code works fine in general, but if the left hand side of the function is one of the arguments, there are some unnecessary constuctor/destructor calls:
curVal = trigger.choose(posVal, curVal); // construct is called in choose, then old curVal is destroyed
Is there some way to improve/avoid this, like if the compiler sees when the left-hand-side of the function is one of the parameters it would run a different code?
Edit:
Here is some sample code: http://ideone.com/nPUK3h
I'd like to know if its possible to ommit the last (4.) construction.
I'll compile this with some more sophisticated optimizations later at home.
Edit2:
I can avoid the additional construction if I introduce the following additional function:
Vec& Vec::setNegative(Vec& target, const Vec& ifNegative) const {
for(int index = 0; index < mSize; ++index) {
if(mData[index] <= 0)
target[index] = ifNegative[index];
}
return target;
}
So if the lhs of the choose-function is the same as the first parameter this produces the same output, however if the lhs is another vector i would like to get a new vector instead.
Is there some way to choose between the two via some template-magic or compiler-technology??
IIRC, RVO permits the compiler to construct the return value in the location of the receiving object, but in this case, a reference to that object is being used in the call, i.e. the return value is being constructed before the parameter is used.
So I can see how this would defeat RVO. I can't see why it would defeat moving though.
Use a C++11 compiler with move semantics. The returned Vec object is nameless, and can be moved from.
Keep in mind that the code as written is strongly exception-safe. If any assignment fails, curVal is untouched. Any "optimization" which works by modifying curVal on the fly is likely to break this.

Access elements of map which is member of vector without creating copy

I have following data type
typedef std::map <std::string.std::string> leaf;
typedef std::map <std::string,leaf> child;
typedef std::vector<child> parent;
Now if I want access parent element at index 0 and child element having key "x" and then perform some operation of it's values
First way of doing this will be like:
parentobject[0]["x"]["r"]
But every time I need to repeat these index whenever I want access that value.
Second way of doing this will be like:
std::string value=parentobject[0]["x"]["r"]
Then use value object. But problem with this approach is this line will create copy of the string.
Is there a better way to access variable without creating copy?
You can use reference to avoid copy:
std::string & value = parentobject[x][y][z];
Or, will you be okay with this instead:
//define a lambda in the scope
auto get = [] (int x, std::string const & y, std::string const & z)
-> std::string &
{
return parentobject[x][y][z];
}
//then use it as many times as you want in the scope
std::string & value = get(0, "x", "r");
get(1, "y", "s") = "modify";
Use a reference:
const std::string& value = parentobject[0]["x"]["r"];
Now you can refer to value anywhere you like (within the same block scope) without having to perform the map lookups again.
Remove the const if you really need to.
Please purchase and read one of these books in order to learn C++'s basic features.