Copy a char vector to another vector - c++

I'm trying to create a function to copy an vector into another one :
#include <iostream>
#include <vector>
int clone(std::vector <char> X, std::vector <char> Y){
for(int i(0);i<X.size();i++){
Y[i]=X[i];
}
return 0;
}
When I call the function, nothing appears on the prompt window.

There are 2 issues with your code. The first is that any modification to Y will not be visible at the call site, since you are passing the vector by value. Instead, you need to pass it by reference.
Second, you are indexing X incorrectly (assuming X is not as large as Y). Instead, you could just push_back the values.
However, you can even copy vectors directly, so you could do:
int clone(std::vector <char> const &X, std::vector <char> &Y){
Y = X;
return 0;
}
At this point, having a named function is rather pointless, since instead of doing something like:
std::vector<char> y;
clone(x, y);
you could simply do:
auto y = x;
which is much more readable.

Related

Vector parameter in a function doesn't seem to actually apply to input?

I have a vector variable named intVec, and I have a function named pushBack, that accepts a vector of type integer just like intVec, but when I actually pass that vector into the function in order to push_back the x parameter, nothing seems to happen.
Output expected from intVec.size() is 1
Output given from intVec.size() is 0
I'm genuinely confused as to what I'm doing incorrectly here.
Perhaps I'm missing something extremely obvious.
#include <vector>
std::vector<int> intVec;
void pushBack(int x, std::vector<int> vec) {
vec.push_back(x);
}
int main() {
pushBack(10, intVec);
std::cout << intVec.size();
}
That is because you pass the vector by value instead of by reference (or pointer).
This means, that when you call the function, the vector you call 'push_back' on is actually an independent copy of the original vector, which get deallocated upon leaving the function.
Try this header instead:
void pushBack(int x, std::vector<int> &vec) {
vec.push_back(x);
}
The & tells the compiler to pass by reference, meaning that whatever you do to vec, you also do to the vector you originally passed.
Write pushBack as below:
void pushBack(int x, std::vector<int>& vec) {
vec.push_back(x);
}
The only difference is that here vec is being passed by reference. In your code it is being passed by value.

How to have a function act on non-argument variables?

I am trying to write a function which will take in multiple indices and do something based on the values in an array at those indices. If I do not declare the arrays as arguments to the function (which will always operate on the same two arrays) I get X/Y was not declared in this scope, but if I do attempt to declare them, I get "error: declaration of ‘X’ as multidimensional array must have bounds for all dimensions except the first," and the bounds are not known until runtime.
Is there any way to do this in a function, or do I have to explicitly write the code in main every time?
Code:
double foo(int A, int B, int t){//A, B, and t are indices
int x = X[A][t]-X[B][t]; //X and Y are 2D arrays
int y = Y[A][t]-Y[B][t];
double d;
//do some math ...
return d;
}
int main{
.
.
.
int X[nPeople][tMax]={0};
int Y[nPeople][tMax]={0};
.
.
.
for(int t=0; t<tMax; t++){
for(int n=0; n<nPeople; n++){
foo(n,a,t);
}
}
.
.
.
return 0;
}
There are multiple ways:
1- Use built-in std::vector library with the following inclusion:
#include <vector>
Vectors are dynamic arrays so when you initialize them they do not have a strict capacity which you can never change. On constrast, they grow larger with each element you push or insert. As far as I can see you are dealing with matrices so you need two dimensional arrays, no problem. Here is the code for it:
std::vector<std::vector<int> >
2- Use global variables. Variables that are declared outside of the functions are considered global so they will be visible to every function beneath it. Altough it is not considered to be good coding practise because of the bugs it may cause in a large scale problem, if you are confident enough that it will not pose a threat to your code safety/cleanness, go ahead use it!
3- Use dynamically allocated arrays and pass the pointers as parameters so that you can deal with any size you want
There are several ways a function can work with data:
Use global data:
std::vector<std::vector<int>> X;
std::vector<std::vector<int>> Y;
double foo(int A, int B, int t){ //A, B, and t are indices
int x = X[A][t]-X[B][t]; // X and Y are global 2D arrays
int y = Y[A][t]-Y[B][t];
double d;
//do some math ...
return d;
}
unfortunately shown too many times in sample code, but (mutable) global have lot of issues (hard to test, hard to re-use the code, hard to reason about the code)
Pass them as arguments:
double foo(const std::vector<std::vector<int>>& X, // X and Y are 2D arrays
const std::vector<std::vector<int>>& Y, // As we can see, so unneeded comment
int A, int B, int t){ //A, B, and t are indices
int x = X[A][t]-X[B][t];
int y = Y[A][t]-Y[B][t];
double d;
//do some math ...
return d;
}
bind them using a class:
class C
{
std::vector<std::vector<int>> X;
std::vector<std::vector<int>> Y;
public:
double foo(int A, int B, int t){ //A, B, and t are indices
int x = X[A][t]-X[B][t]; // X and Y are member 2D arrays (it should be trivial (`this->` might help), so comment not needed neither)
int y = Y[A][t]-Y[B][t];
double d;
//do some math ...
return d;
}
};
care to create coherent classes and avoid god class (which have mostly same default as global).

Can I pass 0 to a function expecting a vector type parameter?

I have a function, as such:
void foo(int checkInt, vector<int> vect, int x) {
EXECx = x;
EXECcheckInt = checkInt;
if (EXECcheckInt > 0) {
//do something to vect
} else {
Timer.rset();
}
}
As can be seen, vect is left alone unless checkInt is above 0. So, if I want to pass checkInt 0, then it seems like I wouldn't have to worry about vect.
Therefore it would seem to me that I need some dummy value to go into this function for vect, so what value would work, or do I need to pass a dummy vector? My idea was to just pass 0, but I'm guessing that wouldn't work.
I tried to cast it, as in foo(0,(vector<int>)0,0), but I was surprised that when I tried to print out vect, it just showed up as empty (no 0 inside it), with the function written as so:
void foo(int checkInt, vector<int> vect, int x) {
for (auto i = vect.begin(); i != vect.end(); ++i)
std::cout << *i << ' ';
}
How should I go about this?
I'm working with C++98.
The code looks like the function decides whether the vector is used or not but what you want to do suggests that it is the caller who decides if the vector is used or not. Who is it really? I think you have a design problem, fix that then you dont need to cast a 0 to a vector anymore. (eg make two functions, one taking a vector, the other taking no vector as parameter)
Anyhow, you may want to look at std::optional which is only available since C++17, but it might give you some inspiration on how to handle such situation in a clean way. The "dirty" way is to pass a pointer and then check if it is a nullptr inside the function.
Your casts does not create a vector filled with 0 but a vector with size 0.
Change the function declaration to accept a reference of the vector to avoid copying memory unnecessarily like so:
void foo(int checkInt, vector<int>& vect, int x)
If you already have a vector object then you can pass that even if it is not used. If you need to construct a dummy vector then you can call the function like this:
vector<int> v;
foo (0, v, x);
You could provide an overload that can be called without the vector. You can refactor the common part into a subfunction:
void foo(int checkInt, vector<int> vect, int x) {
if (checkInt > 0) {
bar(checkInt, x);
//do something to vect
} else {
foo(checkInt, x);
}
}
void foo(int checkInt, int x) {
assert(checkInt <= 0); // maybe unnecessary. depends on what you need
bar(checkInt, x);
Timer.rset();
}
void bar(int checkInt, int x) {
EXECx = x;
EXECcheckInt = checkInt;
}
// with vect
foo(checkInt, vect, x);
// without vect
foo(0, 0);
but I was surprised that when I tried to print out vect, it just showed up as empty (no 0 inside it)
It's unclear why that surprises you. As per documentation, the constructor of vector that accepts an integer creates that many elements into the constructed vector. A vector with 0 elements is empty.
Note that you probably should reconsider whether you would want to pass the vector by value. Are you sure that you need a copy?

Copy std::vector but apply lambda to each element

I have got a std::vector X of std::vector of, say, double in C++.
How can I transform X into a std::vector Y of int such that X[i].size() == Y[i] holds for all admissible indices i?
std::vector< std::vector<int> > X;
...
/* What I want to do should look as follows */
std::vector<int> Y = std::copy_and_transform( X, lambda_to_get_size );
Of course, this can be realized with a loop, but in C++11 we would like to use lambdas instead. I have not found anything like that in std::algorithm. The standard tools seem to only give in place transformations that change the original vector and which do not allow changing the data type.
You can use std::transform:
std::vector<int> Y;
std::transform(X.cbegin(), X.cend(), std::back_inserter(Y), [](const std::vector<int>& value) {
return value.size();
});

C++ returning an array

I'm new to C++ programming and i want to make a function that gives you all the common dividers into an array, and afterwards use it in int main()
Is returning an array from a function possible :D?
Thank you!
Code: http://pastebin.com/K8195wzF
Returning a dynamically-sized container like std::vector has the best use case here:
#include <vector>
...
std::vector<int> dividers(int x, int y) {
std::vector<int> divi;
...
return divi;
}
Returning by value creates a copy, ensuring no dangling pointers. Such is the case when returning a local array through a pointer: the memory will be lost when the function exits leaving the pointer to point to garbage.
Yes it is possible to return an array in form of a pointer, but this is not recommended as you won't know its size in advance. But take care not to return the address of a local variable (allocated on the stack!!). Another problem with your code is that you didn't initialize d. The preferred C++ way would be to return a vector of the type (you do not need d anymore)
#include <vector>
....
vector<int> dividers(int y,int x){
int yx;
vector<int> divi;
divi.reserve(100);
if(y > x){
yx = y;
}
if(x > y){
yx = x;
}
for (int n = 1; n <= yx; n++){
if ((n%y==0) && (n%x==0)){
divi.push_back(n);
}
}
return divi;
}
You should read about iterators too to modify the loop that is in your main function.
Big mistake in my code removed... Thanks for pointing it out. I did the same mistake with vector that what you had with the array. Fixed now... Stupid me...
No it's not possible. You could return a vector, or you could pass a pointer to the first element of an array to your function.
Looking at your code, the pointer option would look something like this
int dividers(int y,int x, int* divi){
...
}
int main()
{
int divi[100];
...
dividers(x, y, divi);
}
The vector solution might look like this
std::vector<int> dividers(int y,int x){
std::vector<int> divi;
...
divi.push_back(n); // when you want to add a divider to your vector
...
return divi;
}
int main()
{
std::vector<int> divi;
...
divi = dividers(x, y);
}
You could do the following:
typedef int arrT[10]
arrT *func() {}
whereby one is defining arrT to be an alias of an array of 10 ints or
int (*func())[10]{}
whereby one is defining func when dereferenced to return an array of 10 ints.
A using declaration such that using arrT = int[10] is also possible.
As others have noted, returning a std::vector from a function containing the type desired is possible with a function declared as std::vector<int> func(){}.
Also, you could use another container std::array<> and forget built-in arrays altogether.
Reference: C++ Primer; Lippman, Lajoie, Moo