Add element to function in place C++
Python code:
l1 = [1, 2, 3]
l2 = l1 + [4]
print(l2) #[1, 2, 3, 4]
l3 = l1+l2
print(l3) #[1, 2, 3, 1, 2, 3, 4]
Is there a way to do this in C++
You clarified in a comment that you want to do it "in place". In C++17 there isn't an operator or function in the standard library for concatenating two vectors (or containers), but it is pretty easy to create one yourself:
template <class T>
std::vector<T> concat(const std::vector<T>& v1, const std::vector<T>& v2)
{
auto res = v1;
res.insert(res.end(), v2.begin(), v2.end());
return res;
}
In C++20 all this changes as we will get ranges.
Until then you can use the ranges-v3 library (on which the standard ranges are based):
views::concat(v1, v2);
This returns a range. That should be enough as you should take range views as parameters or at least iterators. The advantage is that views are lazy. They don't do the actual transformations until you iterate over them and don't create new containers. If you however still need a vector you can do that like this:
#include <range/v3/view.hpp>
using namespace ranges;
auto test()
{
std::vector v1{10, 20, 30};
std::vector v2{1, 2, 3, 4, 5};
auto v = views::concat(v1, v2) | to<std::vector>();
}
There has been a comment about creating an overloaded operator+ instead of the function. That would be a bad idea for a few reasons:
Overloading an operator with only standard classes as parameters is a bad idea as you can't open namespace std to define it there and defining it elsewhere will cause problems with ADL.
Second, even if you could, a golden rule is to overload an operator to do expected things. In this case, an operator+ would be expected by (some/most) people to do element-wise addition.
I believe you're trying to add an element to a vector in c++.
vector<int> v; // { }
v.push_back(10); // { 10 }
To append one vector to another vector, you could use insert
vector<int> v = { 11, 12 };
vector<int> v2 = { 13, 14 };
v.insert(v.end(), v2.begin(), v2.end()); // { 11, 12, 13, 14 }
The first parameter to insert is an iterator pointing to where you want the second vector's elements to be inserted. The 2nd and 3rd parameters are the iterators pointing to the beginning and end of the second vector, they denote the boundaries of which elements to insert into the first vector.
This operation effectively appends the second vector into the first vector.
Related
Is there a standard implementation of a for_each that does call with the element and the next one in the range?
For example take the range {0, 1, 2, 3, 4, 5}, I would like to call a function f with each element and its successor: {f(0, 1), f(1, 2), f(2, 3), f(3, 4), f(4, 5)}
Note how the last element is left out because it has no successor.
It would also be nice if there was a generalization of this to n successors that get passed with the element itself.
Up to now I have always solved this in terms of a handwritten loop with iterators.
However, I would like to go much more along the lines of C++11 range based for or std::for_each to avoid boiler plate code.
Examples
// today: handwritten loop
for(Range::iterator current = range.begin(); current != range.end(); ++current)
f(*current, *std::next(current));
// near future: wrapped version
for_each_pair(range.begin(), range.end(), f);
// slightly further future: generalized version
for_each_tuple<n>(range.begin(), range.end(), f);
Additional Question
The name of the function could be improved. To me for_each_pair/tuple sounds like all subsets of size n of the range should be returned (which is in itself another problem I would like to solve). So I'd like some suggestions on better names like:
for_each_adjacent<n>
Temporary Solution
I have posted my own solution over at CR. I won't duplicate it here because this is about a standard solution and there are already enough roll-your-own answers.
You could actually abuse std::unique or std::adjacent_find for this: the predicate is called with each consecutive pair in the iterator range, and as long as the predicate always returns false, it won't modify anything or return early.
Disregarding that particular hack, I would implement this as an iterator adapter, not an algorithm. That is, I'd implement a consecutive_tuple_iterator<N> which would return all tuples of N consecutive items. Then you could use it for things like count_if and includes, not just for_each. (It wouldn't be appropriate for most modifying algorithms, though.)
The simplest thing would be to write it as a generic algorithm, then apply it many times.
template< typename FwdIter, typename Func >
Func for_each_pair( FwdIter iterStart, FwdIter iterEnd, Func func )
{
if( iterStart == iterEnd )
return func;
FwdIter iterNext = iterStart;
++iterNext;
for( ; iterNext != iterEnd; ++iterStart, ++iterNext )
{
func( *iterStart, *iterNext );
}
return func;
}
As I was asked why it returns func (rather than void), this is typical of a for_each because of the fact that
func could be an object
It is passed by value.
func may "accumulate" some kind of state, but it is the copy we have made into this algorithm that is accumulating it, not the user's original object. We therefore pass them back the modified "func" object.
With C++ 11 and the new iterator helper functions std::next and std::prev for iterators, the second variant of the standard algorithm std::transform can be used to iterate over adjacent elements.
Here is an example that generates a list of adjacent pairs from a list:
std::vector<int> nums{3, 4, 2, 9, 15, 267};
std::vector<std::pair<int,int>> num_pairs;
if (!nums.empty()) {
std::transform(
std::begin(nums), std::prev(std::end(nums)),
std::next(std::begin(nums)),
std::back_inserter(num_pairs),
std::make_pair<
decltype(nums)::const_reference,
decltype(nums)::const_reference
>
);
}
Not exactly what you want, but take a look at cpplinq.
int numbers[] = {0, 1, 2, 3, 4, 5};
auto pairs = cpplinq::from_array(numbers)
>> cpplinq::pairwise()
>> cpplinq::to_vector(); // yields (0,1), (1,2), (2,3), (3,4), (4,5)
for(auto p : pairs)
f(p.first, p.second);
look out for C++23 views::slide(n)
vector<int> ints = {1, 2, 3, 4};
auto rg2 = ints | views::slide(2);
/*
{{1, 2}, {2, 3}, {3, 4}}
*/
auto rg3 = ints | views::slide(3);
/*
{{1, 2, 3},{2, 3, 4}}
*/
I'm just wondering whether there is a simple, quick way to insert the elements of a vector of vectors inside a vector.
For example:
std::vector<std::vector<double> > vals
{
{1, 2, 3, 4, 5, 6},
{1, 2, 3, 4, 5, 6}
};
std::vector<double> myvector;
so myvector would then contain: 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6
I've tried using insert and push_back but had no luck.
Edit:
I have used:
myvector.insert(vals.begin(), vals.end()); - No matching member function to call to 'insert'
Try
// c++11
for(auto && v : vals){
myvector.insert(myvector.end(), v.begin(), v.end());
}
// non c++11
for(std::vector<std::vector<double> >::const_iterator it = vals.begin(), end = vals.end(); it != end; ++it){
myvector.insert(myvector.end(), it->begin(), it->end());
}
Depending on how your vector of vectors is built in the first place, there may be a more efficient way to approach this.
If your sub-vectors are all the same length (as appears to be the case from the code example), then the best thing may be to view myvector as a 2D array and build directly into this buffer.
If the sub-vector lengths can vary, but the code that builds your vector of vectors only ever actually adds stuff at the end, then you can use something like the 'collapsed vector vector' class I describe here to build this data, instead of a vector of vectors.
(And after that, again, your data is already in the kind of contiguous buffer you are looking for.)
Either way, if performance or memory footprint are important here then avoiding the vector of vector construct can eliminate a lot of buffer manipulation overhead, and work out as quite a significant optimisation.
If you want to insert all of the elements of vals into a single vector:
Brute Force Method
for (int i = 0; i < vals.size(); ++i)
{
for (int j = 0; j < vals[i].size(); ++j)
{
myvector.push_back(vals[i][j]);
}
}
More Elegant Method
struct AddVector
{
std::vector<double> myvector;
void operator()(const std::vector<int>& a)
{
std::copy(a.begin(), a.end(), std::back_inserter(myvector));
}
};
// somewhere in your code
AddVector av;
std::for_each(vals.begin(), vals.end(), av);
myvector.swap(av.myvector);
The variable vals is a vector of vectors, but myvector is a vector of doubles. Trying to insert from the first into the second will not work as the contained types are different (std::vector<double> versus double).
Instead you have to manually insert from each sub-vector of vals into myvector.
resize myvector to the size of the sum of the sizes of the vectors in vals. For every vector in vals concat it to myvector. To get a idea how to concat:
Concatenating two std::vectors
I'm using a vector in a C++ program and I need to pass a part of that vector to a function.
If it was C, I would need to do the following (with arrays):
int arr[5] = {1, 2, 3, 4, 5};
func(arr+2); // Pass the part of the array {3, 4, 5}
Is there any other way than creating a new vector with the last part?
A common approach is to pass iterator ranges. This will work with all types of ranges, including those belonging to standard library containers and plain arrays:
template <typename Iterator>
void func(Iterator start, Iterator end)
{
for (Iterator it = start; it !=end; ++it)
{
// do something
}
}
then
std::vector<int> v = ...;
func(v.begin()+2, v.end());
int arr[5] = {1, 2, 3, 4, 5};
func(arr+2, arr+5);
Note: Although the function works for all kinds of ranges, not all iterator types support the increment via operator+ used in v.begin()+2. For alternatives, have a look at std::advance and std::next.
Generically you could send iterators.
static const int n[] = {1,2,3,4,5};
vector <int> vec;
copy (n, n + (sizeof (n) / sizeof (n[0])), back_inserter (vec));
vector <int>::iterator itStart = vec.begin();
++itStart; // points to `2`
vector <int>::iterator itEnd = itStart;
advance (itEnd,2); // points to 4
func (itStart, itEnd);
This will work with more than just vectors. However, since a vector has guaranteed contigious storage, so long as the vector doesn't reallocate you can send the addresses of elements:
func (&vec[1], &vec[3]);
The latest (C++20) approach is to use std::span. Create a std::span that views a part of std::vector and pass it to functions. Note: the elements must be continuous in memory to use std::span on a container, and std::vector is continuous in memory.
#include <span>
std::vector<int> int_vector = {1, 2, 3, 4, 5};
std::span<int> a_span(int_vector.data() + 2, int_vector.size() - 2);
for(const int a : a_span);
for(const int& a : a_span);
function(a_span);
As of C++20, I would make use of a range from the Ranges library, because it offers a variety of range adaptors for creating different views on you vector. For your use case, I would use the range adaptor std::views::drop as follows:
int main() {
std::vector<int> arr {1, 2, 3, 4, 5};
// Ignore the first two elements and pass only {3, 4, 5} to func().
func(arr | std::views::drop(2));
return 0;
}
This way you don't have to bother with interators or pointer/iterator arithmetic.
Also, no temporary vector is created for your shortened arr, because the view adaptor drop() creates a range that doesn't contain elements. The resulting range is just a view over the original vector arr, but with a customized iteration behavior.
For the declaration of func() I would use the placeholder type auto for the function parameter, because the type of the resulting range is quite complex. This makes func() a function template, though:
void func(auto range) {
for (int i : range)
std::cout << i << std::endl;
}
(Alternatively, you could pass arr by reference to func() and apply the range adaptor inside func().)
Output:
3
4
5
Code on Wandbox
std::vector<char> b(100);
send(z,&b[0],b.size(),0);
Try out this.
Read this too.
As some others already stated you can use iterators for that. You'll have to pass the start of the sequence and the end of the sequence to your worker function.
If you need more flexibility, you should take a look at slice. With slice you can for example retrieve every n-th entry of the vector.
I was also stuck to same problem.I found one really nice trick.Suppose you want to find the minimum in range L to R (both inclusive) of arr then you can do something like this:
vector<int>arr = {4,5,1,3,7};
int minVal = *min_element(begin(arr)+L,begin(arr)+(R+1));
Means you pass the complete array and range and then you can apply the above trick.
guys!
I'm trying to understand the work of iterators, so in the code below,is it possible to change back_inserter to front_inserter without changing underlying data (structure).
Could you,please,explain why. If change is possible consider its key idea.
int a1[] = { 0, 1, 2, 3, 4, 5, 6 };
int a2[] = { 1, 4, 5 };
std::vector<int> a3;
int a4[] = { 0, 2, 3, 6 };
std::set_difference(a1, a1 + 7, a2, a2 + 3, std::back_inserter(a3));
assert(std::equal(a3.begin(), a3.end(), a4));
Thank you all!
An insert iterator is simply an implementation of an iterator which inserts something in to a collection using standard mechanisms. In the case of back_inserter, the insertion is done by calling the push_back() method on the container. Hence, in order to use back_inserter, the container must implement push_back().
Likewise, with front_inserter the collection mush implement push_front(), which vector does not. Therefore, you can't use front_inserter on a vector.
list and deque both implement push_front, so if you were to use one of those rather than a vector, you could use front_inserter.
No, but what you want is an inserter:
std::set_difference(a1, a1 + 7, a2, a2 + 3, std::inserter(a3, a3.begin()));
Maybe I am missing something completely obvious, but I can't figure out why one would use back_inserter/front_inserter/inserter,
instead of just providing the appropriate iterator from the container interface.
And thats my question.
Because those call push_back, push_front, and insert which the container's "normal" iterators can't (or, at least, don't).
Example:
int main() {
using namespace std;
vector<int> a (3, 42), b;
copy(a.begin(), a.end(), back_inserter(b));
copy(b.rbegin(), b.rend(), ostream_iterator<int>(cout, ", "));
return 0;
}
The main reason is that regular iterators iterate over existing elements in the container, while the *inserter family of iterators actually inserts new elements in the container.
std::vector<int> v(3); // { 0, 0, 0 }
int array[] = { 1, 2, 3 };
std::copy( array, array+3, std::back_inserter(v) ); // adds 3 elements
// v = { 0, 0, 0, 1, 2, 3 }
std::copy( array, array+3, v.begin() ); // overwrites 3 elements
// v = { 1, 2, 3, 1, 2, 3 }
int array2[] = { 4, 5, 6 };
std::copy( array2, array2+3, std::inserter(v, v.begin()) );
// v = { 4, 5, 6, 1, 2, 3, 1, 2, 3 }
The iterator points to an element, and doesn't in general know what container it's attached to. (Iterators were based on pointers, and you can't tell from a pointer what data structure it's associated with.)
Adding an element to an STL container changes the description of the container. For example, STL containers have a .size() function, which has to change. Since some metadata has to change, whatever inserts the new element has to know what container it's adding to.
It is all a matter of what you really need. Both kinds of iterators can be used, depending on your intent.
When you use an "ordinary" iterator, it does not create new elements in the container. It simply writes the data into the existing consecutive elements of the container, one after another. It overwrites any data that is already in the container. And if it is allowed to reach the end of the sequence, any further writes make it "fall off the end" and cause undefined behavior. I.e. it crashes.
Inserter iterators, on the other hand, create a new element and insert it at the current position (front, back, somewhere in the middle) every time something is written through them. They never overwrite existing elements, they add new ones.