C++ trying to swap values in a vector - c++

This is my swap function:
template <typename t>
void swap (t& x, t& y)
{
t temp = x;
x = y;
y = temp;
return;
}
And this is my function (on a side note v stores strings) call to swap values but whenever I try to call using values in a vector I get an error. I'm not sure what I'm doing wrong.
swap(v[position], v[nextposition]); //creates errors

I think what you are looking for is iter_swap which you can find also in <algorithm>.
all you need to do is just pass two iterators each pointing at one of the elements you want to exchange.
since you have the position of the two elements, you can do something like this:
// assuming your vector is called v
iter_swap(v.begin() + position, v.begin() + next_position);
// position, next_position are the indices of the elements you want to swap

Both proposed possibilities (std::swap and std::iter_swap) work, they just have a slightly different syntax.
Let's swap a vector's first and second element, v[0] and v[1].
We can swap based on the objects contents:
std::swap(v[0],v[1]);
Or swap based on the underlying iterator:
std::iter_swap(v.begin(),v.begin()+1);
Try it:
int main() {
int arr[] = {1,2,3,4,5,6,7,8,9};
std::vector<int> * v = new std::vector<int>(arr, arr + sizeof(arr) / sizeof(arr[0]));
// put one of the above swap lines here
// ..
for (std::vector<int>::iterator i=v->begin(); i!=v->end(); i++)
std::cout << *i << " ";
std::cout << std::endl;
}
Both times you get the first two elements swapped:
2 1 3 4 5 6 7 8 9

There is a std::swap in <algorithm>

after passing the vector by reference
swap(vector[position],vector[otherPosition]);
will produce the expected result.

Using std::swap by including the <algorithm> library to swap values by references / smart pointers,
e.g. std::swap(v[0], v[1])
Note: v[i] is a reference
Using std::iter_swap from the same library,
e.g. std::iter_swap(v.begin(), v.begin() + v.size() - 1)
Using lvalue references and rvalue tuple by including the <tuple> library
e.g. std::tie(v[0], v[1]) = std::make_tuple(v[1], v[0])
Note: constexpr since C++14

Related

Template funtion returning an iterator

i would like to make a reusable function that returns an iterator to make it easy to find the middle point of a container and need some help
fixed;
template <typename T> std::vector<int>::const_iterator middlepoint(std::vector<T> const& arr){
auto temp = arr.begin() + arr.size() / 2;
return temp;
}
the caller:
auto middle_point = middlepoint(arr.begin(), arr.end());
fixed:
template <typename T> int middlepoint(std::vector<T> const& arr){
std::cout << "size: " << arr.size() << endl;
auto middle_point = arr.begin() + (arr.size()/ 2);
int middle_element = middle_point - arr.begin();
return middle_element;
}
caller:
int middle_element = middlepoint(arr);
error:
ambiguous
ambiguous, means you declared 2 functions with the same name, but different parameters.
It looks like you're taking the beginning and end iterators and dividing them by 2 to get the middle position. Iterators don't have a valid expression for division, so what you're doing won't work.
The best way I can think to implement this would be to use the size of the container divided by 2 as an offset from the beginning or the end (whichever works best for you). This way you wouldn't need to pass both iterators to the function.
auto mid = it.begin() + (arr.size() / 2); original
return mid;
If you can't get the size of the container using the .size() method (which you should be able to because you have access to the iterators), you can create a helper function that cycles through and counts. That shouldn't be needed for your case though because you're using a vector.

Why does sizeof(ar)/ sizeof(ar[0]) not work properly on a vector when passed to a function?

I'm trying to get to know c++ better and came across this confusion.
int simpleArraySum(const vector<int> ar) {
int n=sizeof(ar)/sizeof(ar[0]);
int sum=0;
for (int i=0; i<n; i++){
sum+=ar[i];
}
return sum;
}
When I passed a vector of 10 elements the result was lower than expected. I checked that n=6 unlike when I use size() which gives n=10. My confusion comes since the way the code is written works normally in main with sizeof(ar)/sizeof(ar[0]).
Using the "sizeof trick" have never worked on a std::vector.
The size of a std::vector object is the size of the std::vector object itself, not the possible data handled by the vector.
If you want to get the number of elements from a std::vector object, use the size member function.
The "sizeof trick" only works on actual arrays, like e.g.
int array[10];
std::cout << sizeof(array) / sizeof(array[0]) << '\n'; // Will print 10
As for the problem you try to solve with your function, there are much better ways to handle it.
First you could iterate using the size (like you do now)
for (size_t i = 0; i < ar.size(); ++i)
sum += ar[i];
Then you could iterate using iterators
for (auto i = ar.begin(); i != ar.end(); ++i)
sum += *i;
Then you have range-based for loops
for (auto value : ar)
sum += value;
Lastly you can use a standard algorithm function like std::accumulate
int simpleArraySum(std::vector<int> const& ar)
{
return std::accumulate(begin(ar), end(ar), 0);
}
Why does sizeof(ar)/ sizeof(ar[0]) not work properly on a vector ...
sizeof(ar)/ sizeof(ar[0]) is an expression that gives you the length of an array, and only an array. std::vector is not an array. std::vector is a class (template).sizeof(std::vector) is entirely unrelated to the number of elements it has i.e. its length.
The size of all types is compile time constant. std::vector's can contain a variable number of elements that is not compile time constant. Therefore the size of vector type cannot depend on the number of elements.
... when passed to a function?
It won't work when not passing into a function either.

stl::iterators with raw pointers

I want to use iterators with C++ arrays, but with raw pointers too.
I can do with a static vector:
#define SIZE 10
int vect[SIZE] = {0};
vect[3] = 5;
int* p = std::find(std::begin(vect), std::end(vect), 5);
bool success = p != std::end(vect);
How can be possible to do it with a raw pointer (maybe a heap allocated vector)?
Of course the compiler does not know the size of the data, so this code
int* pStart = vect;
std::find(std::begin(pStart), std::end(pStart), 5);
gives
error C2784: '_Ty *std::begin(_Ty (&)[_Size])' :
could not deduce template argument for '_Ty (&)[_Size]' from 'int *'
Is it possible to make begin() and end() aware of it?
Is it possible to make begin() and end() aware of it?
It's possible to implement std::begin for a pointer, but it is impossible to implement std::end (because as you say, the size is unknown), so it is a bit pointless.
However, you don't need either of those to use std::find:
int* p = std::find(pStart, pStart + SIZE, 5);
No it is not possible to use std::begin and std::end on a pointer. Unlike an array whose size is part of the type and therefor deducible a pointer does not hold the size of the thing it points to. In your case with a pointer you would have to use
std::find(pStart, pStart + SIZE, 5);
The way to avoid this though is to use std::vector when you are not going to know what the szie will be at compile time. It will manage the memory for you and provides begin and end member functions.
Here:
std::begin(pStart), std::end(pStart)
you're trying to take the beginning and end of a pointer. Nope!
Instead, you meant:
std::begin(vect), std::end(vect)
This is the same whether you use an array, or a std::array, or a std::vector, or a particularly large elephant — to get the bounds of a container, you need the container.
When I deal with naked arrays I rely on simple containers to make them compatible with C++'s general treatment of ranges.
For example:
#include <iostream>
#include <memory> // for std::unique_ptr
#include <algorithm> // for std::reverse
#include <numeric> // for std::iota
template<typename T>
class range_view {
public:
range_view(T* data, std::size_t size)
: m_data { data },
m_size { size } { }
const T* begin() const { return m_data; }
const T* end() const { return m_data + m_size; }
T* begin() { return m_data; }
T* end() { return m_data + m_size; }
private:
T* m_data;
std::size_t m_size;
};
int main() {
// this is your actual data
auto pdata = std::make_unique<int>(20);
// this is a handle you use to work with your data
auto data_view = range_view<int>(pdata.get(), 20);
// for example, you can fill it with numbers 0, ... , N - 1
std::iota(data_view.begin(), data_view.end(), 0);
// it is now compatible with c++'s range-based operators
std::cout << "my data...\n";
for(auto && item : data_view) std::cout << item << " ";
std::reverse(data_view.begin(), data_view.end());
std::cout << "\nreversed...\n";
for(auto && item : data_view) std::cout << item << " ";
std::cout << "\n";
}
Compile and run
$ g++ example.cpp -std=c++14
$ ./a.out
my data...
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
reversed...
19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
You still have to worry about passing the correct dimension to the constructor, and it will fail miserably if the underlying pointer is deleted, but you had to worry about that anyway.
I want to use iterators with C++ arrays, but with raw pointers too.
You got it backwards. Raw pointers are iterators. They iterate over arrays.
You can just use them for all the things you would otherwise accomplish with std::begin and std::end. Most notably, you can pass them to C++ standard algorithms in <algorithm>.
A pointer itself cannot be iterated. Iterators cannot be iterated.
int* pStart = vect;
std::find(std::begin(pStart), std::end(pStart), 5);
Very loosely speaking, a pointer is just a number. What is the "begin" and "end" of a number? This piece of code makes as little sense as the following:
int i = 123;
std::find(std::begin(i), std::end(i), 5); // error
Is it possible to make begin() and end() aware of it?
A pointer may point to the beginning of some array. But that knowledge must be kept along with the pointer. You need to maintain a size or an end pointer along with a start pointer, and keep all that data together.
That's exactly what std::array and std::vector do for you.
While others answers already explains why you should revisit your design I want to state one option, that was not described earlier.
Your compiler diagnosis message almost clearly states that the compiler falls to deduce arguments and that arguments looks exactly like reference to С-style array.
Reference to C-style array doesn't decay to pointer, so you can pass reference to C-style array to std::begin and std::end in that particular case as an option:
#include <iostream>
#include <algorithm>
constexpr size_t SIZE = 10;
int main() {
int vect[SIZE] = {0};
vect[3] = 5;
int (&ref_to_vect)[SIZE] = vect; // declaring reference to C-array
// and using reference to C-array which doesn't decay to pointer opposite to passing array "by value" semantics
int* p = std::find(std::begin(ref_to_vect), std::end(ref_to_vect), 5);
bool success = p != std::end(vect);
std::cout << (success ? "Found 5" : "5 not found :(");
return 0;
}

valarray divide its element

When I divide a valarray by its first element, only the first element becomes 1 and others keep their original value.
#include <iostream>
#include <valarray>
using namespace std;
int main() {
valarray<double> arr({5,10,15,20,25});
arr=arr/arr[0]; // or arr/=arr[0];
for(int value:arr)cout << value << ' ';
return 0;
}
The actual output is:
1 10 15 20 25
The expected output is:
1 2 3 4 5
Why is the actual output not as expected?
I use g++(4.8.1) with -std=c++11
This one works:
#include <iostream>
#include <valarray>
using namespace std;
int main() {
valarray<double> arr({5,10,15,20,25});
auto v = arr[0];
arr=arr/v; // or arr/=arr[0];
for(int value:arr)cout << value << ' ';
return 0;
}
The problem is that you are trying to use a value (arr[0]) from an array that you are modifying at the same time (arr).
Intuitively, once you have updated arr[0] by doing arr[0]/arr[0], what value does it contain?
Well, that's the value that will be used from now on to divide the other values...
Please, note that the same applies for arr/=arr[0] (first of all, arr[0]/arr[0] takes place, than all the others, in a for loop or something like that).
Also note from the documentation that operator[] of a std::valarray returns a T&. This confirms the assumption above: it is turned to 1 as the first step of your iteration, then all the other operations are useless.
By simply copying it solves the issue, as in the example code.
The details of why this happens are due to implementation tricks used in valarray to improve performance. Both libstdc++ and libc++ use expression templates for the results of valarray operations, rather than performing the operations immediately. This is explicitly allowed by [valarray.syn] p3 in the C++ standard:
Any function returning a valarray<T> is permitted to return an object of another type, provided all the
const member functions of valarray<T> are also applicable to this type.
What happens in your example is that arr/arr[0] doesn't perform the division immediately, but instead it returns an object like _Expr<__divide, _Valarray, _Constant, valarray<double>, double> which has a reference to arr and a reference to arr[0]. When that object is assigned to another valarray the division operation is performed and the result stored directly into the left-hand side of the assignment (this avoids creating a temporary valarray to store the result and then copying it into the left-hand side).
Because in your example the left-hand side is the same object, arr, it means that the reference to arr[0] stored in the expression template refers to a different value once the first element in arr has been updated with the result.
In other words, the end result is something like this:
valarray<double> arr{5, 10, 15, 20, 25};
struct DivisionExpr {
const std::valarray<double>& lhs;
const double& rhs;
};
DivisionExpr divexpr = { arr, arr[0] };
for (int i = 0; i < size(); ++i)
arr[i] = divexpr.lhs[i] / divexpr.rhs;
The first iteration of the for-loop will set arr[0] to arr[0] / arr[0] i.e. arr[0] = 1, and then all subsequent iterations will set arr[i] = arr[i] / 1 which means the values don't change.
I'm considering making a change to the libstdc++ implementation so that the expression template will store a double directly instead of holding a reference. This would mean arr[i] / divexpr.rhs will always evaluate arr[i] / 5 and not use the updated value of arr[i].

How to pass a vector to another vector push back? (without creating a extra variable to pass)

Well I am questioning myself if there is a way to pass a vector directly in a parameter, with that I mean, like this:
int xPOS = 5, yPOS = 6, zPOS = 2;
//^this is actually a struct but
//I simplified the code to this
std::vector <std::vector<int>> NodePoints;
NodePoints.push_back(
std::vector<int> {xPOS,yPOS,zPOS}
);
This code ofcourse gives an error; typename not allowed, and expected a ')'
I would have used a struct, but I have to pass the data to a Abstract Virtual Machine where I need to access the node positions as Array[index][index] like:
public GPS_WhenRouteIsCalculated(...)
{
for(new i = 0; i < amount_of_nodes; ++i)
{
printf("Point(%d)=NodeID(%d), Position(X;Y;Z):{%f;%f;%f}",i,node_id_array[i],NodePosition[i][0],NodePosition[i][1],NodePosition[i][2]);
}
return 1;
}
Ofcourse I could do it like this:
std::vector <std::vector<int>> NodePoints;//global
std::vector<int> x;//local
x.push_back(xPOS);
x.push_back(yPOS);
x.push_back(zPOS);
NodePoints.push_back(x);
or this:
std::vector <std::vector<int>> NodePoints;//global
std::vector<int> x;//global
x.push_back(xPOS);
x.push_back(yPOS);
x.push_back(zPOS);
NodePoints.push_back(x);
x.clear()
but then I'm wondering which of the two would be faster/more efficient/better?
Or is there a way to get my initial code working (first snippet)?
Use C++11, or something from boost for this (also you can use simple v.push_back({1,2,3}), vector will be constructed from initializer_list).
http://liveworkspace.org/code/m4kRJ$0
You can use boost::assign as well, if you have no C++11.
#include <vector>
#include <boost/assign/list_of.hpp>
using namespace boost::assign;
int main()
{
std::vector<std::vector<int>> v;
v.push_back(list_of(1)(2)(3));
}
http://liveworkspace.org/code/m4kRJ$5
and of course you can use old variant
int ptr[1,2,3];
v.push_back(std::vector<int>(ptr, ptr + sizeof(ptr) / sizeof(*ptr));
If you don't have access to either Boost or C++11 then you could consider quite a simple solution based around a class. By wrapping a vector to store your three points within a class with some simple access controls, you can create the flexibility you need. First create the class:
class NodePoint
{
public:
NodePoint( int a, int b, int c )
{
dim_.push_back( a );
dim_.push_back( b );
dim_.push_back( c );
}
int& operator[]( size_t i ){ return dim_[i]; }
private:
vector<int> dim_;
};
The important thing here is to encapsulate the vector as an aggregate of the object. The NodePoint can only be initialised by providing the three points. I've also provided operator[] to allow indexed access to the object. It can be used as follows:
NodePoint a(5, 6, 2);
cout << a[0] << " " << a[1] << " " << a[2] << endl;
Which prints:
5 6 2
Note that this will of course throw if an attempt is made to access an out of bounds index point but that's still better than a fixed array which would most likely seg fault. I don't see this as a perfect solution but it should get you reasonably safely to where you want to be.
If your main goal is to avoid unnecessary copies of vector<> then here how you should deal with it.
C++03
Insert an empty vector into the nested vector (e.g. Nodepoints) and then use std::swap() or std::vector::swap() upon it.
NodePoints.push_back(std::vector<int>()); // add an empty vector
std::swap(x, NodePoints.back()); // swaps contents of `x` and last element of `NodePoints`
So after the swap(), the contents of x will be transferred to NodePoints.back() without any copying.
C++11
Use std::move() to avoid extra copies
NodePoints.push_back(std::move(x)); // #include<utility>
Here is the explanation of std::move and here is an example.
Both of the above solutions have somewhat similar effect.