Hi guys,
Is there a way to return a functor from a recursive call that takes
different paths? Let's say that I have a tree structure like:
root
|
first child ---- nextSibling ----nextSibling ----nextSibling
---->0
| |
| |
0 |
0 0
firstChild -0
|
0
Now, I would like to create a function that executes a functor on leaf
objects. Is this possible???
In code, let's say we have a tree class:
template <class Object>
class Tree {
struct TreeNode {
TreeNode() : obj_(), firstChild_(NULL), nextSibling_(NULL),
parent_(NULL), depth_() {}
TreeNode(Object obj) : obj_(obj), firstChild_(NULL),
nextSibling_(NULL), parent_(NULL), depth_() {}
Object obj_;
size_t depth_;
TreeNode* firstChild_;
TreeNode* nextSibling_;
TreeNode* parent_;
};
TreeNode* root_; //!< The root of the tree
TreeNode* current_; //!< Helper pointer for searches
size_t size_; //!< Number of nodes in the tree
size_t height_; //!< Tree height
public:
typedef Object ValueType;
typedef Object& ReferenceType;
typedef Object* IteratorType;
//! Default constructor
Tree() : size_() { root_ = current_ = NULL; }
// more constructors, assignment operator and destructor...
// functions to return size and height...
template <class Functor>
Functor LeafExecute(Functor fn) {
//set current to root to start execution
current_ = root_;
//uses the private function FindObject
return LeafExecute(current_, fn);
}
private:
template <class Functor>
Functor LeafExecute(TreeNode* ptr, Functor fn) {
//recursively executes the rest of the tree
if (ptr->nextSibling_ != NULL)
LeafExecute(ptr->nextSibling_,fn);
if(ptr->firstChild_ != NULL)
LeafExecute(ptr->firstChild_,fn);
else if (ptr->firstChild_ == NULL) {
// execute functor
cout<<"executing functor at depth "<<ptr->depth_<<endl;
fn(ptr->obj_);
return fn;
}
}
};
I'm following the same behavior as the for_each algorithm in the
standard library:
template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function
__f)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept< _InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__f(*__first);
return __f;
}
except that it doesn't work as I expected and I don't know why. Maybe
because I'm calling the recursion on the siblings? Note that the
functor is passed by value to the function and returned by value (of
course)
I appreciate any feedback.
aa 2 2261
aaragon wrote:
Hi guys,
Is there a way to return a functor from a recursive call that takes
different paths? Let's say that I have a tree structure like:
root
|
first child ---- nextSibling ----nextSibling ----nextSibling
---->0
| |
| |
0 |
0 0
firstChild -0
|
0
Now, I would like to create a function that executes a functor on leaf
objects. Is this possible???
In code, let's say we have a tree class:
template <class Object>
class Tree {
struct TreeNode {
TreeNode() : obj_(), firstChild_(NULL), nextSibling_(NULL),
parent_(NULL), depth_() {}
TreeNode(Object obj) : obj_(obj), firstChild_(NULL),
nextSibling_(NULL), parent_(NULL), depth_() {}
Object obj_;
size_t depth_;
TreeNode* firstChild_;
TreeNode* nextSibling_;
TreeNode* parent_;
};
TreeNode* root_; //!< The root of the tree
TreeNode* current_; //!< Helper pointer for searches
size_t size_; //!< Number of nodes in the tree
size_t height_; //!< Tree height
public:
typedef Object ValueType;
typedef Object& ReferenceType;
typedef Object* IteratorType;
//! Default constructor
Tree() : size_() { root_ = current_ = NULL; }
// more constructors, assignment operator and destructor...
// functions to return size and height...
template <class Functor>
Functor LeafExecute(Functor fn) {
//set current to root to start execution
current_ = root_;
//uses the private function FindObject
return LeafExecute(current_, fn);
}
private:
template <class Functor>
Functor LeafExecute(TreeNode* ptr, Functor fn) {
//recursively executes the rest of the tree
if (ptr->nextSibling_ != NULL)
LeafExecute(ptr->nextSibling_,fn);
if(ptr->firstChild_ != NULL)
LeafExecute(ptr->firstChild_,fn);
else if (ptr->firstChild_ == NULL) {
// execute functor
cout<<"executing functor at depth "<<ptr->depth_<<endl;
fn(ptr->obj_);
return fn;
}
}
};
I'm following the same behavior as the for_each algorithm in the
standard library:
template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function
__f)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept< _InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__f(*__first);
return __f;
}
except that it doesn't work as I expected and I don't know why.
What do you expect and where does it differ?
The only difference I is that you create copies of the functor object during
the execution and that many of the changes will be lost. E.g., when you
call
LeafExecute(ptr->nextSibling_,fn);
the current functor is passed by value, and any modification to its state
will be lost. As a consequence, if you try to count the number of leaves
using a stateful functor, you will miscount.
You could either replace those lines by
fn = LeafExecute( ptr->nextSibling_, fn );
or pass the functor by reference internally, e.g.:
template <class Functor>
Functor LeafExecute(Functor fn) {
assert( root_ != NULL );
LeafExecute(root_, fn);
return( fn );
}
private:
template <class Functor>
void LeafExecute(TreeNode* ptr, Functor & fn) {
//recursively executes the rest of the tree
if (ptr->nextSibling_ != NULL) {
LeafExecute(ptr->nextSibling_,fn);
}
if(ptr->firstChild_ != NULL) {
LeafExecute(ptr->firstChild_,fn);
} else {
// leaf: execute functor
fn(ptr->obj_);
}
}
Maybe
because I'm calling the recursion on the siblings? Note that the
functor is passed by value to the function and returned by value (of
course)
I appreciate any feedback.
aa
Best
Kai-Uwe Bux
On Apr 30, 1:37 am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
aaragon wrote:
Hi guys,
Is there a way to return a functor from a recursive call that takes
different paths? Let's say that I have a tree structure like:
root
|
first child ---- nextSibling ----nextSibling ----nextSibling
---->0
| |
| |
0 |
0 0
firstChild -0
|
0
Now, I would like to create a function that executes a functor on leaf
objects. Is this possible???
In code, let's say we have a tree class:
template <class Object>
class Tree {
struct TreeNode {
TreeNode() : obj_(), firstChild_(NULL), nextSibling_(NULL),
parent_(NULL), depth_() {}
TreeNode(Object obj) : obj_(obj), firstChild_(NULL),
nextSibling_(NULL), parent_(NULL), depth_() {}
Object obj_;
size_t depth_;
TreeNode* firstChild_;
TreeNode* nextSibling_;
TreeNode* parent_;
};
TreeNode* root_; //!< The root of the tree
TreeNode* current_; //!< Helper pointer for searches
size_t size_; //!< Number of nodes in the tree
size_t height_; //!< Tree height
public:
typedef Object ValueType;
typedef Object& ReferenceType;
typedef Object* IteratorType;
//! Default constructor
Tree() : size_() { root_ = current_ = NULL; }
// more constructors, assignment operator and destructor...
// functions to return size and height...
template <class Functor>
Functor LeafExecute(Functor fn) {
//set current to root to start execution
current_ = root_;
//uses the private function FindObject
return LeafExecute(current_, fn);
}
private:
template <class Functor>
Functor LeafExecute(TreeNode* ptr, Functor fn) {
//recursively executes the rest of the tree
if (ptr->nextSibling_ != NULL)
LeafExecute(ptr->nextSibling_,fn);
if(ptr->firstChild_ != NULL)
LeafExecute(ptr->firstChild_,fn);
else if (ptr->firstChild_ == NULL) {
// execute functor
cout<<"executing functor at depth "<<ptr->depth_<<endl;
fn(ptr->obj_);
return fn;
}
}
};
I'm following the same behavior as the for_each algorithm in the
standard library:
template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function
__f)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept< _InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__f(*__first);
return __f;
}
except that it doesn't work as I expected and I don't know why.
What do you expect and where does it differ?
The only difference I is that you create copies of the functor object during
the execution and that many of the changes will be lost. E.g., when you
call
LeafExecute(ptr->nextSibling_,fn);
the current functor is passed by value, and any modification to its state
will be lost. As a consequence, if you try to count the number of leaves
using a stateful functor, you will miscount.
You could either replace those lines by
fn = LeafExecute( ptr->nextSibling_, fn );
or pass the functor by reference internally, e.g.:
template <class Functor>
Functor LeafExecute(Functor fn) {
assert( root_ != NULL );
LeafExecute(root_, fn);
return( fn );
}
private:
template <class Functor>
void LeafExecute(TreeNode* ptr, Functor & fn) {
//recursively executes the rest of the tree
if (ptr->nextSibling_ != NULL) {
LeafExecute(ptr->nextSibling_,fn);
}
if(ptr->firstChild_ != NULL) {
LeafExecute(ptr->firstChild_,fn);
} else {
// leaf: execute functor
fn(ptr->obj_);
}
}
Maybe
because I'm calling the recursion on the siblings? Note that the
functor is passed by value to the function and returned by value (of
course)
I appreciate any feedback.
aa
Best
Kai-Uwe Bux
Thanks for replying to my post. I tried the first approach and it
didn't work, so I ended up passing internally by reference as you
suggested. That solved the problem. The final code for the function
looks like this:
template <class Functor>
Functor LeafExecute(Functor fn) {
assert(root_ != NULL);
//set current to root to start execution
current_ = root_;
//uses the private function FindObject
LeafExecute(current_, fn);
return fn;
}
template <class Functor>
Functor& LeafExecute(TreeNode* ptr, Functor& fn) {
//recursively executes the rest of the tree
if (ptr->nextSibling_ != NULL)
LeafExecute(ptr->nextSibling_,fn);
if(ptr->firstChild_ != NULL)
LeafExecute(ptr->firstChild_,fn);
else if (ptr->firstChild_ == NULL) {
// execute functor
cout<<"executing functor at depth "<<ptr->depth_<<endl;
fn(ptr->obj_);
return fn;
}
}
where this time I return by reference in the private function.
Once again, thanks!
aa This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: replace-this-with-my-name |
last post by:
Hi.
How do I return a string containing an entire menu-tree from a
recursive function?
Here is my current recursive function:
function page_tree( $_i ){
//Call global mysql connection...
|
by: Paul Chiusano |
last post by:
I've been playing around with generators and have run into a
difficulty. Suppose I've defined a Node class like so:
class Node:
def __init__(self, data=None, left=None, right=None):...
|
by: Derek Rhodes |
last post by:
using
Python 2.3.4 (#53, May 25 2004, 21:17:02) on
win32
OK, I have a recursive function that should return a list, but doesn't
<start session>
def test(word):
if type(word) == str:
|
by: Jon Slaughter |
last post by:
#pragma once
#include <vector>
class empty_class
{
};
template <int _I, int _J, class _element, class _property>
class RDES_T
{
|
by: Roshan Naik |
last post by:
typedef int foo ( foo ); // foo is a pointer-to-function type that takes
another foo as argument and returns an int
I need to achieve the above effect somehow. This is not accepted by any...
|
by: Seong-Kook Shin |
last post by:
Hi, I'm reading Steve's "C Programming FAQs" in book version,
and have two question regarding to Q11.16
... Also, a `return' from `main' cannot be expected to work if
data local to main might be...
|
by: samuelberthelot |
last post by:
Hi,
I'm trying to write a recursive fucntion that takes as parameters a
html div and an id. I have to recurse through all the children and
sub-children of the div and find the one that matches the...
|
by: Fabian Steiner |
last post by:
Hello!
I have got a Python "Device" Object which has got a attribute (list)
called children which my contain several other "Device" objects. I
implemented it this way in order to achieve a kind...
|
by: Belebele |
last post by:
I have an Element class which is abstract and I would like to have an
object of the Iterator class to iterate over a range of elements.
I would like to use std::for_each to instrument the...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
| |