passing vector to function c++ - c++

I have a main.cpp test.h and test.cpp> I am trying to pass my vector through so i can use it in test.cpp but i keep getting errors.
//file: main.cpp
int main(){
vector <Item *> s;
//loading my file and assign s[i]->name and s[i]-address
tester(s);
}
//file: test.h
#ifndef TEST_H
#define TEST_H
struct Item{
string name;
string address;
};
#endif
//file: test.cpp
int tester(Item *s[]){
for (i=0; i<s.sizeof();i++){
cout<< s[i]->name<<" "<< s[i]->address<<endl;
}
return 0;
}
---------------errors--------
In file included from main.cpp:13:
test.h:5: error: âstringâ does not name a type
test.h:6: error: âstringâ does not name a type
main.cpp: In function âint main()â:
main.cpp:28: error: cannot convert âstd::vector<Item*, std::allocator<Item*> >â to âItem**â for argument â1â to âint tester(Item**)â

A std::vector<T> and T* [] are not compatible types.
Change your tester() function signature as follows:
//file: test.cpp
int tester(const std::vector<Item>& s) // take a const-reference to the std::vector
// since you don't need to change the values
// in this function
{
for (size_t i = 0; i < s.size(); ++i){
cout<< s[i]->name<<" "<< s[i]->address<<endl;
}
return 0;
}
There are several ways you could pass this std::vector<T> and all have slightly different meanings:
// This would create a COPY of the vector
// that would be local to this function's scope
void tester(std::vector<Item*>);
// This would use a reference to the vector
// this reference could be modified in the
// tester function
// This does NOT involve a second copy of the vector
void tester(std::vector<Item*>&);
// This would use a const-reference to the vector
// this reference could NOT be modified in the
// tester function
// This does NOT involve a second copy of the vector
void tester(const std::vector<Item*>&);
// This would use a pointer to the vector
// This does NOT involve a second copy of the vector
// caveat: use of raw pointers can be dangerous and
// should be avoided for non-trivial cases if possible
void tester(std::vector<Item*>*);

Pass it as std::vector<Item *> & (reference to vector) and use iterator to iterate through it.

You should #include <string>.
string name should read std::string name etc. Same goes for std::vector.
You're calling tester() with a vector, yet it expects an array (the two are not interchangeable).
s.sizeof() is incorrect for both an array and a vector; for the latter, use s.size() or, better yet, use an iterator.
These are just the errors that immediately jump out; there may be more.

A vector is not an array.
int tester(vector<Item *> &s)
(pass as a reference to avoid copying or if you need to modify)
You also need to modify your code inside the tester function to work correctly as a vector.

You should fix
test.h:5: error: âstringâ does not name a type
first, probably by using namespace std; and #include <string>

You are missing includes
#include <string>
#include <vector>
and you need to use std::string and std::vector<>. A std::vector is not an array, so you should pass the vector as reference
int tester(std::vector<Item*> & vec) { //... }
or even as const std::vector<Item*> & if you are not going to modify the passed vector.
Also, are you sure, that you'll need a vector of pointers? What are you trying to achieve?

Related

passing an array into a class function from another class's constructor

Sorry for the confusing title, basically I have created two classes, one is an object, and the other being a box that contains an array of such objects. so what I want to do is create a function/constructor inside the object class that takes in an array of ints and stores them inside the box. I want to be able to call this function through the box class constructor to initialize these objects. So ive tried something like below but it isnt working at all, since only the first value of the array gets passed through. What am I doing wrong?
#include <iostream>
#include <string>
class object{
string objectName;
int values[];
public:
void createObject(int[]);
}
class Box{
object objects[100];
public:
Box();
}
Box::Box (void){
int array1[2];
int array2[15];
object[1].createObject(array1);
object[2].createObject(array2);
}
Object::Object(int Values[]){
values = Values;
}
You should really use std::vector. The problem with arrays is that they decay to pointers when passed as arguments to functions. As a consequence, If you want to store a private copy of the elements you are forced to use heap-allocated objects and consequently do memory management by hand (with all the pain it causes).
It is much better to rely on data members that permit applying the rule of zero.
Here's a tentative solution:
#include <iostream>
#include <string>
#include <vector>
class object {
public:
object(std::vector<int> const& v, std::string const& object_name): v_(v.begin(), v.end()), object_name_(object_name) {}
private:
std::vector<int> v_;
std::string object_name_;
};
class box {
public:
box(std::vector<object> const& objects): objects_(objects) {};
private:
std::vector<object> objects_;
};
I recommend you instead use a std::vector. Arrays don't really work well being passed to functions. When you define Object::Object(int Values[]) you are simply passing the first element of this array by value. If you were to use vectors, the function would look like this:
Object::Object(std::vector<int> &Values):
values(Values)
{
}
The problem with the code is in your thinking on what the array is. In C++, all an array is, is a memory pointer. The language allows you to pass an index into the array pointer to access whatever chunk of data lives at that index.
Whenever you pass arrays between functions or classes, pass the array name only. It will be interpreted as a pointer, and won't copy any data. When you do this, you must also pass the length of the array.
Granted, most people stick with vector<> because it's easier, takes care of memory leaks (mostly) and is VERY efficient. But I like doing it myself. It's good for you. I would try:
#include <iostream>
#include <string>
class Object
{
string _objectName;
int *_values;
int _myLength;
Object();
~Object();
void createObject(int *pValues, int arrLength);
}
class Box
{
_Object objects[100];
Box();
}
Box::Box(void) {
int array1[2];
int array2[15];
object[1].createObject(array1, 2);
object[2].createObject(array2, 15);
}
Object::Object() {
_values = null_ptr;
_myLength = 0;
}
Object::~Object() {
delete[] _values;
}
void Object::createObject(int *pvalues, int arrLength) {
_myLength = arrLength;
_values = new int[_myLength];
for(int ndx=0; ndx<arrLength; ndx++) {
_values[ndx] = pvalues[ndx];
}
}
-CAUTION-
I just adapted your code you provided, and added some conventions. There are a couple places in the code where I'm not sure what the purpose is, but there you go. This should give you a good head start.

Using function pointers in std::map

I'm a newbie to C++ and having an issue regarding std:map with function pointers.
I have created a map which has a string as the key and stored a function pointer as the value. I faced a complication when I tried to use insert() function to add a function pointer. However, it worked when I used [] operator. If you can, please explain this difference.
Here is a sample code I wrote.
OperatorFactory.h
#ifndef OPERATORFACTORY_H
#define OPERATORFACTORY_H
#include <string>
#include <map>
using namespace std;
class OperatorFactory
{
public:
static bool AddOperator(string sOperator, void* (*fSolvingFunction)(void*));
static bool RemoveOperator(string sOperator);
static void RemoveAllOperators();
private:
static map<string , void* (*) (void*)> map_OperatorMap;
};
// Static member re-declaration
map<string, void* (*) (void*)> OperatorFactory::map_OperatorMap;
#endif // OPERATORFACTORY_H
OperatorFactory.cpp
#include "OperatorFactory.h"
void OperatorFactory::RemoveAllOperators()
{
map_OperatorMap.clear();
}
bool OperatorFactory::RemoveOperator(string sOperator)
{
return map_OperatorMap.erase(sOperator) != 0;
}
bool OperatorFactory::AddOperator(string sOperator, void* (*fSolvingFunction)(void*))
{
// This line works well.
map_OperatorMap[sOperator] = fSolvingFunction;
// But this line doesn't.
// map_OperatorMap.insert(sOperator, fSolvingFunction); // Error
return true;
}
The Error says :
error: no matching function for call to 'std::map<std::basic_string<char>, void* (*)(void*)>::insert(std::string&, void* (*&)(void*))'
Even though I got this working (compiled) with the [] operator, I would like to know why I got an error when using insert().
Thank you.
You insert elements into std::map using a std::pair of the key and value:
map.insert(std::make_pair(key,value));
Alternatively you can emplace values in c++11:
map.emplace(key,value);
The [] operator returns a reference to the value for the key passed in:
value_type &
And automatically constructs an element for that key if it doesn't already exist. Make sure you understand what the difference in behavior is between insert() and the [] operator before using them (the latter will replace existing values for a key for example).
See http://en.cppreference.com/w/cpp/container/map for more information.

Having a function inside for_each statement

I keep on getting error message while trying to pass a function inside a for_each loop.. I have a vector and i used for_each loop to go through the rows in that vector, Now I need a function to do something
Example this is what I am trying to achieve:
void DataPartitioning::doSomething()
{
for_each (label.begin(), label.end(), addToTemporaryVector());
}
void DataPartitioning::addToTemporaryVector()
{
cout<<"sucess";
}
But I get an error message saying: error: invalid use of void expression both of them are in same class.
Since it's a member function, you'll need to wrap it in a functor that calls it on an object; presumably the same object that doSomething was called on:
for_each(label.begin(), label.end(), [this](whatever const &){addToTemporaryVector();});
where whatever is the value type of the container.
It might be clearer as a regular for-loop:
for (whatever const & thing : label) {
addToTemporaryVector();
}
This assumes you're not stuck with a pre-C++11 compiler. If you are, it requires rather more gibberish:
for_each(label.begin(), label.end(),
std::bind1st(std::mem_fun(&DataPartitioning::addToTemporaryVector), this));
I'm not entirely sure whether that will work with a function like yours that doesn't take an argument; but presumably your real code does take an argument to do something with each element.
You need to use a struct as here:
http://en.cppreference.com/w/cpp/algorithm/for_each
#include <iostream>
#include<string>
#include <vector>
#include <algorithm>
using namespace std;
struct Operation
{
void operator()(string n) { cout<<"success"<<endl; }
};
int main() {
vector<string> vInts(10,"abc");
std::for_each(std::begin(vInts), std::end(vInts), Operation());
// your code goes here
return 0;
}
Note that the input of the operator has to be the same as the type in the vector. (string in this example, int in the link)
The addToTemporaryVector function does not use this. So you can declare it as static.
Also, it should take as argument the template type of label
Declaration:
static void addToTemporaryVector(const SomeType & item);
Then just do:
//No parentheses to the function pointer
for_each (label.begin(), label.end(), addToTemporaryVector);

Error when changing a vector value in a class

I am attempting to change a value in a vector which is a variable in a class using a function of a class. When I compile, i get the following errors pointing to the "check[c] = cval;" line:
error C3867: 'acc::check': function call missing argument list; use '&acc::check' to create a pointer to member
error C2109: subscript requires array or pointer type
Note: I have already initialized C to be 0 elsewhere in the program. It might be throwing an error because I am giving the address a variable instead of an integer, but when I substitute the variable with an integer, I still get the same errors.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
class acc
{
public:
void add_Cval(double cval);
private:
vector<double> check(); //vector of all checks
int c; //loop marker for cvals
};
void acc::add_Cval(double cval)
{
check[c] = cval;
c++;
}
vector<double> check(); isn't what you think it is. You just declared a function named check that returns a vector<double>. Get rid of the parenthesis like so vector<double> check;.
Also, your vector<double> is empty, you need to give it some space if you want to do check[c] = cval; (or use check.push_back(cval); instead), allocate the space in the constructor (use "initialization lists" as that is what they are for):
Example:
acc(int vecsize) : check(vecsize), c(0) {}
You might also want to make sure check[c] is a valid position in the vector before assigning anything to it.
check is a method, not a data member, so you need to invoke it - check().
void acc::add_Cval(double cval)
{
check()[c] = cval;
c++;
}
or make it a data member:
class acc
{
public:
void add_Cval(double cval);
private:
vector<double> check; //vector of all checks
int c; //loop marker for cvals
};
The compiler is looking for a function called check() that returns a vector of type double.
private:
vector<double> check(); // A private function that returns a vector of type <double>
Needs to be:
private:
vector<double> check; // A private data member

reference error

I have a header in which I declare a function. Then I create the function and try to use it but i get an error. It is by reference but I don't know why it is not working.
struct.h
#ifndef LISTSTRUC_H_
#define LISTSTRUC_H_
template <class T> struct Array{
int days;
T * M;
Array( int size ) : days(size), M(new T[size])
{
}
~Array()
{
delete[] M;
}
};
void currentDay();
template <class Expe>
void dummyData(Array<Expe> &);
#endif /* LISTSTRUC_H_ */
struct.cpp
void dummyData(Array <Expe> &A){
for(int i=0; i<31; i++){
A.M[i].Expe::setObj((i*3),(i*1),(i*6),(i*2),(i*4),(i*5));
}
}
M.cpp(Main cpp)
int main(){
//Main function of the program. no pre/ post condition.
Array <Expe> A(31); // Work space
Array <Expe> B(31); // Backup space
dummyData(&A); // error
}
ERROR:
..\M.cpp:22:14: error: no matching function for call to 'dummyData(Array<Expe>*)'
dummyData(&A);
should be:
dummyData(A);
Rationale:
Your function takes a reference not a pointer, &A means you are passing address of the type which can only be received in by a pointer to that type and you don't have that overloaded version of the function, hence the error.
If passing object by reference, don't pass its address, like you did here:
dummyData(&A);
Just pass the object itself (as reference is its alias):
dummyData(A);
You shouldn't put reference & to pass a variable by reference, simply pass it.
dummyData(A);
Passing by reference means that you are not copying the object, instead you are using the object itself and, if passed as variable (not const) changes will affect it.
dummyData(&A);
should be
dummyData(A);
The & operator in this context is taking the address of A which is a pointer. To pass a reference you just use the actual variable name.