pointer to function c++ - c++

guys! I am trying to do this:
int (*filterFunc)(Medicine* criteria, Medicine*);
DynamicVector<Medicine>* filter2(Medicine* criteria, filterFunc f); //error
but I get an error: 'filterFunc' is not a type
I am trying to do this because I want a general filter so then I can do this:
int filterPrice(Pet* pet) {
if (pet->price > 10 && pet->price < 100) {
return 0;
}
return 1;
}
VectorDinamic* filter2(Pet* criteria, filterFunc f) {
VectorDinamic* v = getAll(ctr->repo);
VectorDinamic* rez = creazaVectorDinamic();
int nrElems = getNrElemente(v);
int i;
for (i = 0; i < nrElems; i++) {
Pet* pet = get(v, i);
if (!f(criteria, pet)) {
add(rez, copyPet(pet));
}
}
return rez;
}
VectorDinamic* filterByPrice(float price) {
Pet* criteria = createPet(1, "", "", price);
VectorDinamic* rez = filter2(ctr, criteria, filterByPriceGr);
destroyPet(criteria);
return rez;
}
How can I solve this problem?

You forgot a typedef, to declare the type. Otherwise this declaration just creates a variable of type int(*)(Medicine*,Medicine*).
typedef int (*filterFunc)(Medicine* criteria, Medicine*);
//^^^^^^^

Related

How to add/update/delete Department in university class? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 10 months ago.
Improve this question
#include <iostream>
using namespace std;
class Professor
{
string name;
long employeeID;
string designation;
public:
Professor()
{
name = "";
employeeID = 0;
designation = "";
}
Professor(string n, long ID, string d)
{
name = n;
employeeID = ID;
designation = d;
}
void setProfessorData(string name1, long ID1,string d1)
{
name = name1;
employeeID = ID1;
designation = d1;
}
string getName()
{
return name;
}
long getID()
{
return employeeID;
}
string getDesignation()
{
return designation;
}
};
class Department
{
private:
string name;
long deptID;
Professor profList[5];
int noOfprofessors;
public:
Department()
{
name = "";
deptID = 0;
for (int i = 0; i < 5; i++)
{
profList[i].setProfessorData ("",0,"");
}
noOfprofessors = 0;
}
Department(string name1, long id1, Professor array[5], int no_of_dpt)
{
name = name1;
deptID = id1;
for (int i = 0; i < 5; i++)
{
profList[i] = array[i];
}
noOfprofessors = no_of_dpt;
}
void setDepartmentData(string n, long i, Professor arr[5], int nd)
{
name = n;
deptID = i;
for (int i = 0; i < 5; i++)
{
profList[i] = arr[i];
}
noOfprofessors = nd;
}
string getName1()
{
return name;
}
long getDeptId()
{
return deptID;
}
int getnoOfProfessors()
{
return noOfprofessors;
}
};
class University
{
private:
string name;
Department dept[5];
int numberOfDepartments;
public:
University(string n, Department array[5], int no)
{
name = n;
for (int i = 0; i > 5; i++)
{
dept[i] = array[i];
}
numberOfDepartments = no;
}
void setUniversityData(string name1, Department arr[5], int n1)
{
name = name1;
for (int i = 0; i < 5; i++)
{
dept[i] = arr[i];
}
numberOfDepartments = n1;
}
bool addDepartment(Department D)
{
}
bool deleteDepartment(string name)
{
}
bool updateDepartment(int id, string name)
{
}
};
How to add, delete, and update Department in University class?
I have provided the skeleton code. I have implemented all constructors and destructors, but I don't know how to implement addDepartment(), deleteDepartment(), and updateDepartment()`. Kindly look into this and help me to complete this task.
First off, several of your for loops are incorrect, namely the ones in the following methods:
Department::Department(string, long, Professor[5], int), should be using no_of_dpt (or better, std::min(no_of_dpt, 5)) instead of 5 for the loop counter.
Department::setDepartmentData(), should be using nd (or better, std::min(nd, 5)) instead of 5 for the loop counter.
University::University(string, Department[5], int), should be using no (or better, std::min(no, 5)) instead of 5 for the loop counter. Also, the loop needs to use < instead of >.
University::setUniversityData(), should be using n1 (or better, std::min(n1, 5)) instead of 5 for the loop counter.
That being said, you already have basic logic for adding elements to arrays, so you can implement addDepartment() by applying that logic correctly, eg:
bool addDepartment(Department D)
{
if (numberOfDepartments < 5)
{
dept[numberOfDepartments] = D;
++numberOfDepartments;
}
}
And, you can easily implement deleteDepartment(), you just need to find the index of the desired Department and shift the remaining departments down 1 element in the array, eg:
bool deleteDepartment(string name)
{
for (int i = 0; i < numberOfDepartments; ++i)
{
if (dept[i].getName1() == name)
{
for(int j = i+1; j < numberOfDepartments; ++j)
{
dept[j-1] = dept[j];
}
--numberOfDepartments;
dept[numberOfDepartments].setDepartmentData("", 0, NULL, 0);
break;
}
}
}
Unfortunately, you cannot implement updateDepartment() with the current code you have shown. This is because University does not have access to update the Department::name field directly, and it does not have access to a Department's existing professor data in order to call Department::setDepartmentData() with just a new name.
So, you will have to fix this issue first, either by making University be a friend of Department, or by adding a Department::setName() setter, or by adding getters for the data in the Department::profList array.
However, once you have addressed that, you can then implement updateDepartment(), eg:
class Department
{
private:
string name;
...
friend class University;
public:
...
};
class University
{
private:
...
public:
...
bool updateDepartment(int id, string newName)
{
for (int i = 0; i < numberOfDepartments; ++i)
{
if (dept[i].getDeptId() == id)
{
dept[i].name = newName;
break;
}
}
}
};
Or:
class Department
{
private:
string name;
...
public:
...
void setName(string newName)
{
name = newName;
}
};
class University
{
private:
...
public:
...
bool updateDepartment(int id, string newName)
{
for (int i = 0; i < numberOfDepartments; ++i)
{
if (dept[i].getDeptId() == id)
{
dept[i].setName(newName);
break;
}
}
}
};
Or:
class Department
{
private:
...
Professor profList[5];
int noOfprofessors;
public:
...
Professor* getProfessors()
{
return profList;
}
int getnoOfProfessors()
{
return noOfprofessors;
}
};
class University
{
private:
...
public:
...
bool updateDepartment(int id, string newName)
{
for (int i = 0; i < numberOfDepartments; ++i)
{
if (dept[i].getDeptId() == id)
{
dept[i].setDepartmentData(newName, dept[i].getDeptId(), dept[i].getProfessors(), dept[i].getnoOfProfessors());
break;
}
}
}
};

Array of functions where i-th element returns i

Yesterday my friend challenged me to write a function in C which would return an array of function pointers where i-th function would return i.
It is easy to get a similar effect in C++, but I am not sure how to do it in C.
Can anyone help me with that?
Edit.
The effect that I am looking for is something equivalent to this.
vector <function<int()>> get_functions(int n) {
vector <function<int()>> functions;
for (int i = 0; i < n; ++i) {
functions.emplace_back([i]() {
return i;
});
}
return functions;
}
int main() {
auto functions = get_functions(10);
for (auto f:functions) {
cout << f() << endl;
}
return 0;
}
Edit.
As asked in the comment section I provide my poor attempt on the challenge.
typedef int (*fun_t)(void);
int fun() { return 0; }
int fun1() { return 1; }
fun_t *get_functions() {
fun_t *functions = malloc(sizeof(fun_t) * 2);
functions[0] = fun;
functions[1] = fun1;
return functions;
}
int main() {
fun_t* funs=get_functions();
for (int i = 0; i < 2; ++i) {
printf("%d\n",funs[i]());
}
free(funs);
}
The C++ code is cheating. function<int()> is not a function pointer; in fact, it's not a pointer at all, it's a class.
Therefore the equivalent C code would look something like this:
#include <stdio.h>
#include <stdlib.h>
// function<int ()>, simplified version just for this task
typedef struct {
int (*code)(int);
int ctx;
} function_int_t;
// function<int()>::operator()()
int call(function_int_t fun) {
return fun.code(fun.ctx);
}
// lambda body
int proto(int ctx) {
return ctx;
}
function_int_t *get_functions(size_t n) {
function_int_t *functions = calloc(n, sizeof *functions);
if (!functions) {
abort(); // hey, that's how C++ does it
}
for (size_t i = 0; i < n; i++) {
functions[i] = (function_int_t){ proto, i }; // capture i
}
return functions;
}
int main(void) {
size_t n = 10;
function_int_t *functions = get_functions(n);
for (size_t i = 0; i < n; i++) {
printf("%d\n", call(functions[i]));
}
free(functions);
return 0;
}

Converting from Money class to Int Fails

Compilation error is:
'initializing': cannot convert from 'int' to 'Money'
File: genericarray.h
Line: 13
This is my main function
int main()
{
genericArray<Money>m3(5);
Money d(-1, 89);
Money a(10, 5);
Money b(10, 5);
Money c(43, 7);
Money k(50, 6);
Money m(10, 20);
Money bonus(5, 0);
m3.elements[0] = a;
m3.elements[1] = b;
m3.elements[2] = c;
m3.elements[3] = k;
m3.elements[4] = m;
m3.total = m3.sum();
m2.total = m2.sum();
m1.total = m1.sum();
return 0;
}
This is my Assignment operator overloading of Money class and Money class itself
class Money
{
private:
int lira;
int kurus;
public:
Money() { lira = 0; kurus = 0; }
Money(int a, int b);
~Money() {}
void operator=(const Money& money2) { this->lira = money2.lira; this->kurus = money2.kurus; }
void operator=(int l) { this->lira = l; this->kurus = 0; }
This is my genericArray class with sum() function
template <class Type>
class genericArray
{
private:
int size;
public:
Type* elements;
Type total;
Type sum()
{
Type sumAll = 0;
for (int i = 0; i < size; i++)
{
sumAll += elements[i];
}
if (sumAll > 100)
sumAll += 5;
return sumAll;
}
genericArray() { elements = NULL; size = 0; }
genericArray(int arrSize) { elements = new Type[arrSize]; size = arrSize; }
~genericArray() { delete[] elements; }
};
Writing a new constructor with a single int parameter solved the problem:
Money(const int a)
{
if (a < 0) throw "The amount of money can not be below zero!";
this->lira = a;
this->kurus = 0;
}
The point is that
Type sumAll = 0;
calls only the constructor which takes only 1 int instead of calling the default constructor and the assignment operator.

C++ Bubble sort dynamically allocated array

I wrote a bubble sorting algorithm which sorts a dynamically allocated array using string comparison.
Here is my code:
void AddressBook::bubble_sort_address_book(){
bool swapped = true;
while(swapped){
swapped = false;
for(int i = 0; i < noOfEmployees; i++){
if(employees[i].combined_name() > employees[i+1].combined_name()){
Employee temp_employee = employees[i+1];
employees[i+1] = employees[i];
employees[i] = temp_employee;
}
}
}
}
My problem is pretty obvious, yet I can not seem to figure out how to solve it: The code sometimes fails on the line (in an undefined manner) :
Employee temp_employee = employees[i+1]
Its pretty obvious because if i is equal to the end of the array, accessing memory with i+1 results in undefined behaviour. However, if I stop the for loop with noOfEmployees-1, this does not happen but the first element is never sorted (obviously).
How can I implement bubble sort properly? It seems as such a trivial task. Am I missing something?
The following simplified version in pure C works fine:
int employees[10]= {3,1,7,6,9,7,1,0,2,6};
int noOfEmployees= 10;
void bubble_sort_address_book(void){
bool swapped = true;
int i;
while(swapped){
swapped = false;
for(i = 0; i < noOfEmployees-1; i++){
if(employees[i] > employees[i+1]){
int temp_employee = employees[i+1];
employees[i+1] = employees[i];
employees[i] = temp_employee;
swapped= true;
}
}
}
}
int main()
{
int i;
bubble_sort_address_book();
for (i=0; i<noOfEmployees; i++) {
printf("emp %d= %d\n", i, employees[i]);
}
return 0;
}
As you request, the function of variable swapped is to indicate that following a complete pass through the array no swap occurred and so it indicates the array is now sorted.
You can use an explicit bound on the outer loop.
You should also split things out into smaller functions.
bool operator <(Employee const & lhs, Employee const & rhs) {
return lhs.combined_name() < rhs.combined_name();
}
// a.k.a. std::swap
void swap(Employee & lhs, Employee & rhs) {
Employee temp(static_cast<Employee&&>(lhs)); // a.k.a. std::move
lhs = static_cast<Employee&&>(rhs);
rhs = static_cast<Employee&&>(temp);
}
void bubble_sort_impl(Employee * begin, Employee * end) {
for (; end != begin; --end) {
for (Employee * it = begin; it+1 != end; ++it) {
if (*(it+1) < *it) {
swap(*it, *(it+1));
}
}
}
}
// do we really need "bubble_" or "_address_book" in this name?
void AddressBook::bubble_sort_address_book() {
bubble_sort_impl(employees, employees + noOfEmployees);
}
another solution:
#include <iostream>
#include <vector>
using namespace std;
int employees[10] = { 3,1,7,6,9,7,1,0,2,6 };
void bubble_sort_address_book(void) {
bool swapped = true;
int i;
int noOfEmployees = 10;
while (swapped) {
swapped = false;
for (i = 1; i <= noOfEmployees ; i++) {
if (employees[i] > employees[i - 1]) {
int temp_employee = employees[i - 1];
employees[i - 1] = employees[i];
employees[i] = temp_employee;
swapped = true;
}
}
}
}
int main()
{
int i;
int noOfEmployees = 10;
bubble_sort_address_book();
for (i = 0; i<noOfEmployees; i++) {
printf("emp %d= %d\n", i, employees[i]);
}
return 0;
}

C++ Combinatoric check that subset of conditions are met

I want to ensure as an example that 2/3 values are within a given threshold. The code below accomplishes this but I'm wondering if there is a more generic approach.
struct foo {
int id;
float item1;
float item2;
float item3;
}
bool ConditionCheck(foo val1, foo val2, foo val3) {
int count = 0;
if (abs(val1.item1 - val2.item1) < val3.item1) {
count++;
}
if (abs(val1.item2 - val2.item2) < val3.item2) {
count++;
}
if (abs(val1.item3 - val2.item3) < val3.item3) {
count++;
}
if (count >= 2) {
return true;
}
return false;
}
The issue stems for the custom structs else having parameters as arrays:
// assuming array holds: [id, item1, item2, item3]
bool ConditionCheck(float (&val1)[4], float (&val2)[4], float(&threshold)[4]) {
int count = 0;
for (unsigned int i = 1; i < 4; ++i) {
if (abs(val1[i] - val2[i]) < threshold[i]) {
count++;
}
}
if (count >= 2) {
return true;
}
return false;
}
You can use an array of pointers to member:
bool ConditionCheck(foo val1, foo val2, foo val3) {
float foo::* ptrs[3] = { &foo::item1, &foo::item2, &foo::item3 };
return std::count_if( &ptrs[0],
&ptrs[3],
[&](float foo::* p)
{
return abs(val1.*p - val2.*p) < val3.*p;
}) >= 2;
}