Only got rough idea of what I want, perhaps someone could pad it out and/or tell me if its possible.
I would like to simplify my multiply nested loops, to that end I would like to be able to call a function (for example that uses boost::filesystem) that returns a file in a directory, each successive call would return the next file, until all were exhausted. Also i would like to be able to do this with a vector, and have the function return successive elements.
Any ideas how this could be done? thanks
Create a functor: an object that is called like a function.
The object will hold the query results and the current state of the query. You define an operator() so the object can be called as if it were a function. Each time this function is called you return one result and update the object's internal state.
Example:
#include <iostream>
using namespace std;
class CountDown {
unsigned count;
public:
CountDown(unsigned count) : count(count) {}
bool operator()() { return count-- > 0; }
};
int main()
{
CountDown cd(5);
while( cd() ) {
cout << "Counting" << endl;
}
return 0;
}
use Iterator pattern. In Java you'd have smth like this:
class FileIterator {
private int index;
private File[] files;
public FileIterator(File[] files) {
this.files = files;
this.index = 0;
}
public boolean hasNext() {
if (index < files.length - 1) {
return true;
} else {
return false;
}
}
public File next() {
return this.files [index ++];
}
}
and you'd use it like this:
FileIterator it = new FileIterator(theFiles);
while (it.hasNext()) {
File f = it.next();
}
You can use BOOST_FOREACH to simplify loops link to docs and stackoverflow
Related
So I'm trying to write a recursive function that keeps track of how often it got called. Because of its recursive nature I won't be able to define an iterator inside of it (or maybe it's possible via a pointer?), since it would be redefined whenever the function gets called. So i figured I could use a param of the function itself:
int countRecursive(int cancelCondition, int counter = 0)
{
if(cancelCondition > 0)
{
return countRecursive(--cancelCondition, ++counter);
}
else
{
return counter;
}
}
Now the problem I'm facing is, that the counter would be writeable by the caller of the function, and I want to avoid that.
Then again, it wouldn't help to declare the counter as a const, right?
Is there a way to restrict the variable's manipulation to the function itself?
Or maybe my approach is deeply flawed in the first place?
The only way I can think of solving this, is to use a kind of "wrapper-function" that keeps track of how often the recursive function got called.
An example of what I want to avoid:
//inside main()
int foo {5};
int countToZero = countRecursive(foo, 10);
//countToZero would be 15 instead of 5
The user using my function should not be able to initially set the counter (in this case to 10).
You can take you function as is, and wrap it. One way I have in mind, which completely encapsulates the wrapping is by making your function a static member of a local class. To demonstrate:
int countRecursive(int cancelCondition)
{
struct hidden {
static int countRecursive(int cancelCondition, int counter = 0) {
if(cancelCondition > 0)
{
return countRecursive(--cancelCondition, ++counter);
}
else
{
return counter;
}
}
};
return hidden::countRecursive(cancelCondition);
}
Local classes are a nifty but rarely seen feature of C++. They possess some limitations, but fortunately can have static member functions. No code from outside can ever pass hidden::countRecursive an invalid counter. It's entirely under the control of the countRecursive.
If you can use something else than a free function, I would suggest to use some kind of functor to hold the count, but in case you cant, you may try to use something like this using friendship to do the trick:
#include <memory>
class Counter;
int countRecursive(int cancelCondition, std::unique_ptr<Counter> counter = nullptr);
class Counter {
int count = 0;
private:
friend int countRecursive(int, std::unique_ptr<Counter>);
Counter() = default; // the constructor can only be call within the function
// thus nobody can provide one
};
int countRecursive(int cancelCondition, std::unique_ptr<Counter> c)
{
if (c == nullptr)
c = std::unique_ptr<Counter>(new Counter());
if(cancelCondition > 0)
{
c->count++;
return countRecursive(--cancelCondition, std::move(c));
}
else
{
return c->count;
}
}
int main() {
return countRecursive(12);
}
You can encapsulate the counter:
struct counterRecParam {
counterRecParam(int c) : cancelCondition(c),counter(0) {}
private:
int cancelCondition;
int counter;
friend int countRecursive(counterRecParam);
};
Now the caller cannot modify the counter, and you only need to modify the function slightly:
int countRecursive(counterRecParam crp)
{
if(crp.cancelCondition > 0)
{
--crp.cancelCondition;
++crp.counter;
return countRecursive(crp);
}
else
{
return crp.counter;
}
}
And the implicit conversion lets you call it with an int
counterRecursive(5);
One way to do this is to use a functor. Here's a simple example:
#include <iostream>
class counter
{
public:
unsigned operator()(unsigned m, unsigned n)
{
// increment the count on every iteration
++count;
// rest of the function
if (m == 0)
{
return n + 1;
}
if (n == 0)
{
return operator()(m - 1, 1);
}
return operator()(m - 1, operator()(m, n - 1));
}
std::size_t get_count() const
{
return count;
}
private:
// call count
std::size_t count = 0;
};
int main()
{
auto f = counter();
auto res = f(4, 0);
std::cout << "Result: " << res << "\nNumber of calls: " << f.get_count() << std::endl;
return 0;
}
Output:
Result: 13
Number of calls: 107
Since the count is stored in the object itself, the user cannot overwrite it.
Have you tried using "static" counter variable. Static variables gets initialized just once, and are best candidates to be used as counter variables.
I'm trying to write a "conditions" class to check if a given condition returns true or false, in an rpg game.
Conditions.h
#pragma once
#include <functional>
#include <vector>
#include <iostream>
class Conditions
{
public:
bool check(int i);
void initialize();
private:
std::vector<std::function<bool()>> functions;
};
Conditions.cpp
bool Conditions::check(int i)
{
if (i >= functions.size())
{
std::cout << "Conditions::functions's size is " << functions.size() << " but you've tried to enter: " << i << std::endl;
return false;
}
else
{
return functions[i]();
}
}
void Conditions::initialize()
{
//Here I want to initialize all the conditions manually and push them
//into functions member variable.
}
the question is , how can I create this functions without creating new member functions for each of them(there will be most likely more than 200 functions)
is it possible to write something like:
functions.push_back(
{
if(GameInfo::player.gold>200) return true;
else return false;
}
);
You are probably looking for lambdas:
functions.push_back([this]
{
if (GameInfo::player.gold > 200) return true;
else return false;
});
If you don't actually need to access any members of Conditions in the function, then you can also remove the this capture entirely:
functions.push_back([]
{
if (GameInfo::player.gold > 200) return true;
else return false;
});
By the way, your specific function example can be extremely simplified like this:
functions.push_back([]
{
return GameInfo::player.gold > 200;
});
I have an open hash table using the STL.
typedef std::list<int> LIST;
typedef std::vector<LIST> HASH_TABLE;
I initialized the hash table by filling it with empty lists.
LIST mt_list;
HASH_TABLE hTable;
hTable.assign(7, mt_list);
Now if I want to add an int to my table based on:
hKey = (value*value) % 7;
and I use
hTable[hKey].push_back(value);
It should work right? I can't get it to work.
void addValue(int value){
if(val_find(value)){
std::cout << "WARNING: duplicate input: " << value << std::endl;
}
else{
calc_hash_bucket(value); //set hKey
hTable[hKey].push_back(value); //push value into list
}
}
The code above does not add the element to any of the lists within the vector.
Also, when I want to use an iterator to traverse the vector and the lists within the vector, how do I get one element at a time from a list so I can find a particular value that may or may not already be in the list?
This is what I have for finding a value within the hash table:
bool val_find(int value){
if(mt_hash()){
return false;
}
else{
for(HASH_ITER h_iter = hTable.begin(); h_iter != hTable.end(); ++h_iter){
for(LIST_ITER l_iter = h_iter->begin(); l_iter != h_iter->end(); ++l_iter){
if(*l_iter == value){
return true;
}
}
}
}
return false;
}
I'm stumped. I don't understand why it won't add the value to any of the lists.
I feel I should mention this is all in a header file and part of a class that I created. (I don't know if that matters)
Edit: The warning statement does not print. To answer questions, the mt_hash() function checks to see if the hash table is empty and I have checked it several times to make sure it outputs correctly. I fixed the hTable_1 vs hTable difference, they are the same thing. I just forgot to change it when I put it into the question.
bool mt_hash(void){ //is hash table empty?
for(unsigned int i = 0; i < hTable.size(); ++i){
if(!hTable.at(i).empty()){ //if not empty return false
return false;
}
}
return true; //else return true
}
Thanks,
Zach
As Pradhan points out, there is a quite a bit missing. What is the implementation of mt_hash()? Are hTable_1 and hTable the same object?
Below, I've taken your code above, and placed them in a struct with the implied functionality included. Note three changes: hTable replaces hTable_1 in val_find(); addValue() uses a local variable to store the hash key; and mt_hash() is implemented by keeping a simple element count.
#include <list>
#include <vector>
#include <iostream>
#include <iomanip>
struct open_hash {
typedef std::list<int> LIST;
typedef std::vector<LIST> HASH_TABLE;
typedef LIST::const_iterator LIST_ITER;
typedef HASH_TABLE::const_iterator HASH_ITER;
HASH_TABLE hTable;
int nbins;
int elem_count;
explicit open_hash(int nbins_): nbins(nbins_), elem_count(0) {
init_hash();
}
void init_hash() {
LIST mt_list;
hTable.assign(nbins, mt_list);
}
int hash_bucket(int value) const {
return (value*value)%nbins;
}
bool mt_hash() const {
return elem_count==0;
}
bool val_find(int value) const {
if (mt_hash()) {
return false;
}
for (HASH_ITER h_iter = hTable.begin(); h_iter != hTable.end(); ++h_iter){
for (LIST_ITER l_iter = h_iter->begin(); l_iter != h_iter->end(); ++l_iter){
if (*l_iter == value) {
return true;
}
}
}
return false;
}
void addValue(int value) {
if (val_find(value)) {
std::cout << "WARNING: duplicate input: " << value << std::endl;
}
else {
int hKey=hash_bucket(value);
hTable[hKey].push_back(value); //push value into list
++elem_count;
}
}
};
int main() {
open_hash H(7);
std::vector<int> vals={3,1,9,2,10,4,3};
for (int v: vals) {
H.addValue(v);
}
for (int i=1; i<=10; ++i) {
std::cout << "val_find(" << i << "):\t" << std::boolalpha << H.val_find(i) << "\n";
}
}
This produces expected output:
WARNING: duplicate input: 3
val_find(1): true
val_find(2): true
val_find(3): true
val_find(4): true
val_find(5): false
val_find(6): false
val_find(7): false
val_find(8): false
val_find(9): true
val_find(10): true
I suspect the original problem lies in addValue() and val_find() referring to different hash objects, or a problem in mt_hash() misreporting that the table is empty when in fact it is not.
The answer to the this problem is to create the class object of type HASH_TABLE in the main cpp file and then pass it by reference into the function (getCmd) that calls all of the commands and i/o.
I was calling the "getCmd" function in main() and that function (EVERY time it is called) creates a NEW instance of the HASH_TABLE class, effectively "replacing" the previous object with a new, empty object. (though I suspect it did not actually replace the previous object. I think the previous object was still taking up memory but it was not being used)
I didn't post the code for the problem area because I didn't know where the problem was.
Thanks for all your help!
I want to remove elements from a std::list with linear complexity (going through each element in the list only once). I need to do so depending on the value of a variable in the stack:
int somevalue= 5;
int count=0;
mylist.remove_if(
[](MyStructure* s)
{
if (s->somefield==somevalue)
{
count++;
return true;
}
else
return false;
});
Of course, this doesn't work - somevalue is a variable in the stack.
I've tried using template functions, only to realize (after illegal operation on bound member function expression) you can't really use them in this situation. I know I need to make a closure somehow, so I've read this question, but I can't use C++0x yet and I failed to adapt the other answer for my usecase, as I don't really understand if there's some magic to operator.
Alternatively, is there some way to remove an element from a list given the current position of an iterator (without going through the whole list again to find the element)?
In terms of the lambda expression (a c++11 feature), you can capture the somevalue by value like this: [somevalue](...) {...}
You need to capture the variable in the sample code:
int somevalue= 5;
mylist.remove_if( [somevalue](MyStructure* s){ s->somefield==somevalue });
If no C++11 could be used you need to make the functor yourself:
// For static constant check
template <int CheckValue>
struct Equal {
operator()(const MyStructure* s) { return s->somefield == CheckValue; }
};
mylist.remove_if(Equal<5>);
..or..
// For dynamic constant check as the sample code
struct Equal {
Equal(int check_value) : m_check_value(check_value) {}
operator()(const MyStructure* s) { return s->somefield == m_check_value; }
private:
int m_check_value;
};
mylist.remove_if(Equal(somevalue));
You must capture somevalue in your lamdba expression to use it:
Example (live here) :
struct MyStructure
{
int somefield;
};
int main(int argc, char** argv) {
std::list<MyStructure> my_list = { { 1 }, { 2 }, { 1 }, { 3 }, { 2 }, { 1 } };
int somevalue = 2;
my_list.remove_if( [somevalue](MyStructure s){ return s.somefield == somevalue; });
// ^^^^^^
// Capture
for(auto& s : my_list)
std::cout << s.somefield << " ";
return 0;
}
Iterate on the elements to identify which one you want to remove. Use erase to remove the identified elements and continue to iterate from the returned iterator.
Something like that:
int somevalue=5;
std::list<MyStructure*> myList;
// ...
std::list<MyStructure*>::iterator it=myList.begin();
while(it!=myList.end())
{
if ((*it)->somefield==somevalue)
{
it = myList.erase(it);
}
else
{
++it;
}
}
This is what I'm trying to do (this is a simplification of a real project):
int param;
int result;
void isolated(int p) {
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
} catch (...) {
throw "problems..";
}
}
I can't change the way process() works, since this function is not created in the project and is a third-party function. It works with global variables param and result and we can't change this.
The problem appears when isolated() is called back from process() with another parameter. I want to catch this situation, but don't know how to do it, since finally is absent in C++. I feel that I should use RAII technique, but can't figure out how to do it in this case properly.
This is how I can make it with code duplication:
int param;
int result;
void isolated(int p) {
static bool running;
if (running) {
throw "you can't call isolated() from itself!";
}
running = true;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
running = false;
} catch (...) {
running = false; // duplication!
throw "problems..";
}
}
"finally" like situations are handled in C++ using guard objects, that do their finally thing in the destructor. This is IMHO much more powerful approach, because you have to analyze the situation to finalize in order to create a reuseable object. In this case, we need to make process rentrant, because parameters and returns are passed in globals. The solution is to save their values on entry and restore them on exit:
template<class T>
class restorer
{
T &var; // this is the variable we want to save/restore
T old_value; // the old value
restorer(const restorer&);
void operator=(const restorer&);
public:
restorer(T &v) : var(v), old_value(v) {}
~restorer() { var=old_value; }
};
int param;
int result;
int isolated(int p) {
restorer<int> rest_param(param);
restorer<int> rest_result(result);
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
Maybe I didn't get it right, but why don't you use a flag? You want to know when the isolated() is called from the process(), right?
int isolated(int p) {
static int execDeep = 0;
execDeep++;
// your code here
execDeep--;
}
Now you can check 'execDeep' value, > 1 means it is called from the process() while still being executed.
I still don't quite sure how finally is related here, but you could try Boost.ScopeExit if you want to avoid creating a scope guard structure yourself.
Example:
#include <boost/scope_exit.hpp>
#include <cstdio>
int isolated(int p) {
static bool running = false;
if (running) {
printf("Throwing %d\n", p);
throw p;
}
printf("Starting %d\n", p);
running = true;
BOOST_SCOPE_EXIT( (p)(&running) ) { // <--
printf("Stopping %d\n", p); // <--
running = false; // <--
} BOOST_SCOPE_EXIT_END // <--
// ...
if (p)
isolated(p*10);
// ...
printf("Returing %d\n", p);
return 4;
}
int main() {
printf(">> first\n");
isolated(0);
printf(">> second\n");
try {
isolated(1);
printf(">> third (should not be printed.)\n");
} catch(int p) {
printf("Caught %d\n", p);
}
isolated(0);
printf(">> fourth\n");
return 0;
}
Result:
>> first
Starting 0
Returing 0
Stopping 0
>> second
Starting 1
Throwing 10
Stopping 1
Caught 10
Starting 0
Returing 0
Stopping 0
>> fourth
Could this work?
int save = -10000000000;
int param;
int result;
int isolated(int p) {
if (save != -10000000000)
{
// run the other condition
}
else
{
save = p;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
}
If I understand correctly, you want to automatically set the running flag to false at the end of function. If that is the requirement then you can use the ScopeGuard approarch mentioned in the link.