473,398 Members | 2,088 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

template function as function parameter

rg
Hi all,

I was wondering if anyone had dealt with a similar problem. I need to use a
template function as the parameter for a particular function (also template
function).
The program compiles into an object file but then at the final stage it says
that it can't find template function. The platform is WindowsXP Pro, MSCV++
..Net.

More specifically what I want to do is write an atl algorithm that will also
accept another algorithm as a function parameter. This is inteface of the
outer algorithm:

template <class iterator, class outiterator, class Alg>
void transform_slide ( iterator begin, iterator end, outiterator
outbegin, std::size_t slide, Alg alg)
{
std::size_t loop = std::distance( begin, end) / slide;
for ( std::size_t x = 0; x < loop; ++x, ++outbegin, begin =
std::advance( begin, size) ) // only do complete cycles, not parts
*outbegin = alg( begin, std::advance( begin, size) );
}

What I want to do with is perform some calculations on range on a sliding
basis. For example, if I have a array of 1000 values, I may want to
calculate the average of every 100 of those values.

Any help would be appreciated. Many Thanks in advance.

RG
Jul 22 '05 #1
10 1756

"rg" <rg****@hotmail.com> wrote in message
news:ce**********@news.freedom2surf.net...
Hi all,

I was wondering if anyone had dealt with a similar problem. I need to use a template function as the parameter for a particular function (also template function).
The program compiles into an object file but then at the final stage it says that it can't find template function. The platform is WindowsXP Pro, MSCV++ .Net.
Are you falling into the trap where you place template code in the
implementation (.cpp) file instead of placing all of it in the header? See
the FAQ
(http://www.parashift.com/c++-faq-lit...templates.html) for
info about linker errors with templates.
More specifically what I want to do is write an atl algorithm that will also accept another algorithm as a function parameter. This is inteface of the
outer algorithm:

template <class iterator, class outiterator, class Alg>
void transform_slide ( iterator begin, iterator end, outiterator
outbegin, std::size_t slide, Alg alg)
{
std::size_t loop = std::distance( begin, end) / slide;
for ( std::size_t x = 0; x < loop; ++x, ++outbegin, begin =
std::advance( begin, size) ) // only do complete cycles, not parts
*outbegin = alg( begin, std::advance( begin, size) );
}


This may have weird behavior on some inputs. Consider the behavior if the
distance is 1 and the slide is 2, where nothing is performed. Also, you
could accidentally run off the end of the container with the call to
advance(). Maybe something like this would be safer:

template <class iterator, class outiterator, class Alg>
void transform_slide ( iterator begin, iterator end, outiterator
outbegin, std::size_t slide, Alg alg)
{
std::size_t dist = std::distance( begin, end );
for ( std::size_t x = 0; x < dist; x += slide, ++outbegin )
// only do complete cycles, not parts
iterator tmp = std::advance( begin, std::min(slide, dist-x) );
*outbegin = alg( begin, tmp );
begin = tmp;
}

The code above is untested.

--
David Hilsee
Jul 22 '05 #2
"David Hilsee" <da*************@yahoo.com> wrote in message
news:-8********************@comcast.com...
This may have weird behavior on some inputs. Consider the behavior if the
distance is 1 and the slide is 2, where nothing is performed. Also, you
could accidentally run off the end of the container with the call to
advance(). Maybe something like this would be safer:


Sorry, that comment about the end of the container, AFAICT, does not apply
to your code. It applies to the code that I provided if the call to
std::min is removed.

--
David Hilsee
Jul 22 '05 #3
"David Hilsee" <da*************@yahoo.com> wrote in message
news:-8********************@comcast.com...
template <class iterator, class outiterator, class Alg>
void transform_slide ( iterator begin, iterator end, outiterator
outbegin, std::size_t slide, Alg alg)
{
std::size_t dist = std::distance( begin, end );
for ( std::size_t x = 0; x < dist; x += slide, ++outbegin )
// only do complete cycles, not parts
iterator tmp = std::advance( begin, std::min(slide, dist-x) );
*outbegin = alg( begin, tmp );
begin = tmp;
}


And for my final response to myself, I would like to point out that I didn't
even try to understand the comment that I cut-and-pasted from the original
code and made the code I posted almost completely irrelevant. *smacks
forehead*

--
David Hilsee
Jul 22 '05 #4
On Tue, 3 Aug 2004 23:28:34 +0100, rg <rg****@hotmail.com> wrote:
Hi all,

I was wondering if anyone had dealt with a similar problem. I need to
use a
template function as the parameter for a particular function (also
template
function).
The program compiles into an object file but then at the final stage it
says
that it can't find template function. The platform is WindowsXP Pro,
MSCV++
.Net.

More specifically what I want to do is write an atl algorithm that will
also
accept another algorithm as a function parameter. This is inteface of the
outer algorithm:

template <class iterator, class outiterator, class Alg>
void transform_slide ( iterator begin, iterator end, outiterator
outbegin, std::size_t slide, Alg alg)
{
std::size_t loop = std::distance( begin, end) / slide;
for ( std::size_t x = 0; x < loop; ++x, ++outbegin, begin =
std::advance( begin, size) ) // only do complete cycles, not parts
*outbegin = alg( begin, std::advance( begin, size) );
}

What I want to do with is perform some calculations on range on a sliding
basis. For example, if I have a array of 1000 values, I may want to
calculate the average of every 100 of those values.

Any help would be appreciated. Many Thanks in advance.

RG


I think I'd want to see the code that calls transform_slide.

Maybe I've having a bad day but I can't see how a template function (or
any sort of function) could be a suitable argument for class Arg, surely
you need a non-type template argument? Something like

template <class I, class OI, class T>
void transform_slide(I begin, I end, OI outbegin, size_t slide, T
(*Alg)(I, size_t))
{
}

john
Jul 22 '05 #5
On Wed, 04 Aug 2004 06:50:46 +0100, John Harrison
<jo*************@hotmail.com> wrote:

Maybe I've having a bad day but I can't see how a template function (or
any sort of function) could be a suitable argument for class Arg, surely
you need a non-type template argument?


Yeah I've having a bad day, please ignore.

john
Jul 22 '05 #6
rg
Hi,
Thanks for your reply.
The algorithm that I am talking about is indeed in the header (.hpp) file. I
think the problem is that the template function is not actually instantiated
until it is used so when I send a pointer to it, there is nothing to point
at. I'm wondering if there's anything to deal with that. I tried:

using alg< vector<int>::iterator >;

but that didn't work.

Many thanks

RG

"David Hilsee" <da*************@yahoo.com> wrote in message
news:-8********************@comcast.com...

"rg" <rg****@hotmail.com> wrote in message
news:ce**********@news.freedom2surf.net...
Hi all,

I was wondering if anyone had dealt with a similar problem. I need to use
a
template function as the parameter for a particular function (also template
function).
The program compiles into an object file but then at the final stage it

says
that it can't find template function. The platform is WindowsXP Pro,

MSCV++
.Net.


Are you falling into the trap where you place template code in the
implementation (.cpp) file instead of placing all of it in the header?

See the FAQ
(http://www.parashift.com/c++-faq-lit...templates.html) for
info about linker errors with templates.
More specifically what I want to do is write an atl algorithm that will

also
accept another algorithm as a function parameter. This is inteface of

the outer algorithm:

template <class iterator, class outiterator, class Alg>
void transform_slide ( iterator begin, iterator end, outiterator
outbegin, std::size_t slide, Alg alg)
{
std::size_t loop = std::distance( begin, end) / slide;
for ( std::size_t x = 0; x < loop; ++x, ++outbegin, begin =
std::advance( begin, size) ) // only do complete cycles, not parts
*outbegin = alg( begin, std::advance( begin, size) );
}


This may have weird behavior on some inputs. Consider the behavior if the
distance is 1 and the slide is 2, where nothing is performed. Also, you
could accidentally run off the end of the container with the call to
advance(). Maybe something like this would be safer:

template <class iterator, class outiterator, class Alg>
void transform_slide ( iterator begin, iterator end, outiterator
outbegin, std::size_t slide, Alg alg)
{
std::size_t dist = std::distance( begin, end );
for ( std::size_t x = 0; x < dist; x += slide, ++outbegin )
// only do complete cycles, not parts
iterator tmp = std::advance( begin, std::min(slide, dist-x) );
*outbegin = alg( begin, tmp );
begin = tmp;
}

The code above is untested.

--
David Hilsee

Jul 22 '05 #7
rg
Hi,

Thank you for your reply.

I was going to use it to calculate the rms power for each second in a sound
sample. Currently I'm using a rms_slide algorithm but I wanted to make a
more generic algorithm that can be used for sliding against any custom
algorithm.

Many Thanks

RG

"John Harrison" <jo*************@hotmail.com> wrote in message
news:opsb606wa5212331@andronicus...
On Tue, 3 Aug 2004 23:28:34 +0100, rg <rg****@hotmail.com> wrote:
Hi all,

I was wondering if anyone had dealt with a similar problem. I need to
use a
template function as the parameter for a particular function (also
template
function).
The program compiles into an object file but then at the final stage it
says
that it can't find template function. The platform is WindowsXP Pro,
MSCV++
.Net.

More specifically what I want to do is write an atl algorithm that will
also
accept another algorithm as a function parameter. This is inteface of the outer algorithm:

template <class iterator, class outiterator, class Alg>
void transform_slide ( iterator begin, iterator end, outiterator
outbegin, std::size_t slide, Alg alg)
{
std::size_t loop = std::distance( begin, end) / slide;
for ( std::size_t x = 0; x < loop; ++x, ++outbegin, begin =
std::advance( begin, size) ) // only do complete cycles, not parts
*outbegin = alg( begin, std::advance( begin, size) );
}

What I want to do with is perform some calculations on range on a sliding basis. For example, if I have a array of 1000 values, I may want to
calculate the average of every 100 of those values.

Any help would be appreciated. Many Thanks in advance.

RG

I think I'd want to see the code that calls transform_slide.

Maybe I've having a bad day but I can't see how a template function (or
any sort of function) could be a suitable argument for class Arg, surely

you need a non-type template argument? Something like

template <class I, class OI, class T>
void transform_slide(I begin, I end, OI outbegin, size_t slide, T
(*Alg)(I, size_t))
{
}

john

Jul 22 '05 #8
"rg" <rg****@hotmail.com> wrote in message
news:ce**********@news.freedom2surf.net...

I think you might have overlooked John's request:
I think I'd want to see the code that calls transform_slide.


Also, it might be good to know exactly where the caller's code, and any code
it references, is located (defined in "blah.cpp"/declared in "blah.hpp").

--
David Hilsee
Jul 22 '05 #9
rg
Hi,

Sorry for not having replied earlier, been extremely busy. Here is the code:

file stats.hpp
{
#insert...
.....

template <class iterator>
double rms(iterator begin, iterator end) // calculates the Root Mean
Square Power for some range of values
{
return std::sqrt(
std::accumulate(
begin, end, 0.0, boost::bind<double>(
std::plus<double>(), _1,
boost::bind(std::pow, _2, 2)
)
) / std::distance(begin, end)
);
}

template <class iterator, class outiterator>
void rms_slide ( iterator begin, iterator end, outiterator outbegin,
std::size_t slide) // calculates RMS over a sliding frame
{
std::size_t loop = std::distance( begin, end) / slide;
end = begin + slide;
for (
std::size_t x = 0;
x < loop;
++x, ++outbegin, std::advance( begin, slide), std::advance (
end, slide)
) // only do complete cycles, not parts
*outbegin = rms( begin, end );
}

} // end stats.hpp
file main.cpp
{
short * wav = new short[SIZE]; //array contain audio data
std::vector<int> power; // to hold rms power information over time

rms_slide( wav, wav + SIZE, std::back_inserter(power), SLIDE_SIZE );
// calculate RMS power for frames of size SLIDE_SIZE

delete[] wav;
}// end main.cpp
When I did this, I wondered whether I could develop a more generic version
of the slide algorithm which I described in my earlier post. Instead of
calling rms_slide, I would call:

transform_slide (
wav,
wav + SIZE,
std::back_inserter(power),
SLIDE_SIZE,
rms
);

and tell it to apply the rms algorithm over the sliding frame and insert the
value into the output iterator.

Hope it makes sense. Many Thanks for your help.

RG

"David Hilsee" <da*************@yahoo.com> wrote in message
news:dv********************@comcast.com...
"rg" <rg****@hotmail.com> wrote in message
news:ce**********@news.freedom2surf.net...

I think you might have overlooked John's request:
I think I'd want to see the code that calls transform_slide.

Also, it might be good to know exactly where the caller's code, and any

code it references, is located (defined in "blah.cpp"/declared in "blah.hpp").

--
David Hilsee

Jul 22 '05 #10
"rg" <rg****@hotmail.com> wrote in message
news:cf**********@news.freedom2surf.net...
Hi,

Sorry for not having replied earlier, been extremely busy. Here is the code:
file stats.hpp
{
#insert...
....

template <class iterator>
double rms(iterator begin, iterator end) // calculates the Root Mean Square Power for some range of values
{
return std::sqrt(
std::accumulate(
begin, end, 0.0, boost::bind<double>(
std::plus<double>(), _1,
boost::bind(std::pow, _2, 2)
)
) / std::distance(begin, end)
);
}

template <class iterator, class outiterator>
void rms_slide ( iterator begin, iterator end, outiterator outbegin,
std::size_t slide) // calculates RMS over a sliding frame
{
std::size_t loop = std::distance( begin, end) / slide;
end = begin + slide;
for (
std::size_t x = 0;
x < loop;
++x, ++outbegin, std::advance( begin, slide), std::advance (
end, slide)
) // only do complete cycles, not parts
*outbegin = rms( begin, end );
}

} // end stats.hpp
file main.cpp
{
short * wav = new short[SIZE]; //array contain audio data
std::vector<int> power; // to hold rms power information over time

rms_slide( wav, wav + SIZE, std::back_inserter(power), SLIDE_SIZE ); // calculate RMS power for frames of size SLIDE_SIZE

delete[] wav;
}// end main.cpp
When I did this, I wondered whether I could develop a more generic version
of the slide algorithm which I described in my earlier post. Instead of
calling rms_slide, I would call:

transform_slide (
wav,
wav + SIZE,
std::back_inserter(power),
SLIDE_SIZE,
rms
);

and tell it to apply the rms algorithm over the sliding frame and insert the value into the output iterator.

Hope it makes sense. Many Thanks for your help.


How about:

template <class iterator, class outiterator, class fun>
void transform_slide ( iterator begin, iterator end, outiterator
outbegin,
std::size_t slide, fun f )
{
std::cout << "A" << std::endl;
std::size_t loop = std::distance( begin, end ) / slide;
end = begin;
std::advance( end, slide );
for (
std::size_t x = 0;
x < loop;
++x, ++outbegin, begin = end, std::advance(end,slide)
)

*outbegin = f( begin, end );
}

template <class it>
double rms(it beg, it end) {return 0;}

// Allows the compiler to figure out what type the iterator
// should be
struct rms_wrapper {
template <class it>
double operator()(it beg, it end){
return rms(beg,end);
}
};

int main() {
std::vector<double> v;

transform_slide(v.begin(),v.end(),v.begin(),1,rms< std::vector<double>::itera
tor>);
transform_slide(v.begin(),v.end(),v.begin(),1,rms_ wrapper());
}

But didn't you say something about a linker error? Can't find the function,
or something to that effect?

--
David Hilsee
Jul 22 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Lionel B | last post by:
Greetings. The following code compiles ok and does what I'd expect it to do: ---------- START CODE ---------- // test.cpp
5
by: Lionel B | last post by:
Greetings, I am trying to implement "element-wise" arithmetic operators for a class along the following lines (this is a simplified example): // ----- BEGIN CODE ----- struct X { int a,b;
6
by: Brian Ross | last post by:
Hi, I am trying to do something similar to the following: int Func1(int x, int y); double Func2(double x, double y); template <typename FuncT> // <- What would go here class CObjectT {
1
by: sebastian | last post by:
Hi, I'd like to specialize a template function that contains a template parameter. In Example i have the following function declared: .... template < int i > static stupid_object&...
5
by: krishnaroskin | last post by:
Hey all, I've been running into a problem with default values to template'd functions. I've boiled down my problem to this simple example code: #include<iostream> using namespace std; //...
5
by: StephQ | last post by:
This is from a thread that I posted on another forum some days ago. I didn't get any response, so I'm proposing it in this ng in hope of better luck :) The standard explanation is that pointer...
8
by: Jess | last post by:
Hi, I have a template function that triggered some compiler error. The abridged version of the class and function is: #include<memory> using namespace std; template <class T>
6
by: Bartholomew Simpson | last post by:
I'm trying to avoid (or at least, minimize) duplicity of effort. I have the following function: void Permissions::Exists(const unsigned int id, std::vector<Permission>::const_iterator& iter) {...
4
by: David Sanders | last post by:
Hi, I have a class with an integer template parameter, taking values 1, 2 or 3, and a function 'calc' in that class which performs calculations. Some calculations need only be performed if the...
8
by: William Xu | last post by:
Compiling: template <class T = int> T foo(const T& t) {} int main(int argc, char *argv) {} gcc complains:
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
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,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
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...
0
tracyyun
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 using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.