By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,402 Members | 1,107 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,402 IT Pros & Developers. It's quick & easy.

template and typeid

P: n/a
Max
I am trying to find a way to eliminate vararg functions from my code
by packaging the input parameters in stringstreams. Here is an
oversimplified example of what I am trying to do:
Functions FUNC1 and FUNC2 delegate to functions func1 and func2,
respectively. The goal is to delegate to func1 and func2 using an
identical interface provided by the template function
template<typename F>FTEMPL that takes a stringstream as input and
determines which function to delegate by determining the type of the
generic parameter, F. Here is the code (previously I had a vararg
function instead of the template function):

#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo.h>

using namespace std;

// internal functions
void func1(int, double);
void func2(float, char, string);

// wrapper functions
void FUNC1(int, double);
void FUNC2(float, char, string);
typedef void (*FUNC1_PTR)(int, double);
typedef void (*FUNC2_PTR)(float, char, string);

template<typename F>
void FTEMPL(stringstream ss)
{
if(typeid(F).name() == typeid(FUNC1_PTR).name())
{
int n;
double d;

ss >> n >> d;
func1(n, d);
}
if(typeid(F).name() == typeid(FUNC2_PTR).name())
{
float f;
char c;
string s;

ss >> f >> c >> s;
func2(f, c, s);
}
else
{
cout << "Unrecognized type!" << endl;
}
}

void FUNC1(int n, double d)
{
cout << "FUNC1" << endl;
stringstream ss;
ss << n << endl;
ss << d << endl;

FTEMPL<FUNC1_PTR>(ss);
}

void FUNC2(float f, char c, string s)
{
cout << "FUNC2" << endl;
stringstream ss;
ss << f << endl;
ss << c << endl;
ss << s << endl;

FTEMPL<FUNC2_PTR>(ss);
}

void func1(int n, double d)
{
cout << "func1" << endl;
}

void func2(float f, char c, string s)
{
cout << "func2" << endl;
}

int main(int argc, char* argv[])
{
FUNC1(0, 0.0);
FUNC2(0.0f, '0', "bingo");

return 0;
}

When I run the program in debug mode (I use VC++ 6.0), I get the
following error:
HEAP[testVarArg.exe]: Invalid Address specified to RtlValidateHeap(
2f0000, 2f48e0 )
when the template function returns. When I step into the template
function from FUNC1, I see that typeid(F).name() is FUNC2_PTR instead
of FUNC1_PTR.

What am I doing wrong???
Thanks!
P.S. This example is obviously an overkill, but in the actual program
there is quite some code that would go into the template function
before the if conditions and there are 25 functions with different
signatures, not just 2.
Jul 22 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
My result in MS c++.net 2003:

FUNC1
func1
Unrecognized type!
FUNC2
func2

I changed the code from "void FTEMPL(stringstream ss)"
to "void FTEMPL(stringstream& ss)".

Vince
"Max" <mi****@yahoo.com> wrote in message
news:7b**************************@posting.google.c om...
I am trying to find a way to eliminate vararg functions from my code
by packaging the input parameters in stringstreams. Here is an
oversimplified example of what I am trying to do:
Functions FUNC1 and FUNC2 delegate to functions func1 and func2,
respectively. The goal is to delegate to func1 and func2 using an
identical interface provided by the template function
template<typename F>FTEMPL that takes a stringstream as input and
determines which function to delegate by determining the type of the
generic parameter, F. Here is the code (previously I had a vararg
function instead of the template function):

#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo.h>

using namespace std;

// internal functions
void func1(int, double);
void func2(float, char, string);

// wrapper functions
void FUNC1(int, double);
void FUNC2(float, char, string);
typedef void (*FUNC1_PTR)(int, double);
typedef void (*FUNC2_PTR)(float, char, string);

template<typename F>
void FTEMPL(stringstream ss)
{
if(typeid(F).name() == typeid(FUNC1_PTR).name())
{
int n;
double d;

ss >> n >> d;
func1(n, d);
}
if(typeid(F).name() == typeid(FUNC2_PTR).name())
{
float f;
char c;
string s;

ss >> f >> c >> s;
func2(f, c, s);
}
else
{
cout << "Unrecognized type!" << endl;
}
}

void FUNC1(int n, double d)
{
cout << "FUNC1" << endl;
stringstream ss;
ss << n << endl;
ss << d << endl;

FTEMPL<FUNC1_PTR>(ss);
}

void FUNC2(float f, char c, string s)
{
cout << "FUNC2" << endl;
stringstream ss;
ss << f << endl;
ss << c << endl;
ss << s << endl;

FTEMPL<FUNC2_PTR>(ss);
}

void func1(int n, double d)
{
cout << "func1" << endl;
}

void func2(float f, char c, string s)
{
cout << "func2" << endl;
}

int main(int argc, char* argv[])
{
FUNC1(0, 0.0);
FUNC2(0.0f, '0', "bingo");

return 0;
}

When I run the program in debug mode (I use VC++ 6.0), I get the
following error:
HEAP[testVarArg.exe]: Invalid Address specified to RtlValidateHeap(
2f0000, 2f48e0 )
when the template function returns. When I step into the template
function from FUNC1, I see that typeid(F).name() is FUNC2_PTR instead
of FUNC1_PTR.

What am I doing wrong???
Thanks!
P.S. This example is obviously an overkill, but in the actual program
there is quite some code that would go into the template function
before the if conditions and there are 25 functions with different
signatures, not just 2.

Jul 22 '05 #2

P: n/a
On 30 Jun 2004 00:43:24 -0700, Max <mi****@yahoo.com> wrote:

[]
template<typename F>
void FTEMPL(stringstream ss)
[]

Standard stream are not copyable. You might want to pass it by reference.
{
if(typeid(F).name() == typeid(FUNC1_PTR).name())
[]

Why do you compare type_info's names instead of type_info's themselves?

I'm not sure wheather you need a template parameter here because you use it only as an id which may be passed as well as a usual function argument:

void FUNC1(int, double);
void FUNC2(float, char, std::string);

template<class T>
inline
void(*void_fun_ptr_cast(T* t))()
{
return reinterpret_cast<void(*)()>(t);
}

void f(std::stringstream& ss, void(*id)())
{
if(void_fun_ptr_cast(&FUNC1) == id)
{
}
if(void_fun_ptr_cast(&FUNC2) == id)
{
}
else
{
}
}

int main()
{
std::stringstream s;
f(s, void_fun_ptr_cast(&FUNC1));
f(s, void_fun_ptr_cast(&FUNC2));
}

When I run the program in debug mode (I use VC++ 6.0), I get the
following error:
HEAP[testVarArg.exe]: Invalid Address specified to RtlValidateHeap(
2f0000, 2f48e0 )


Have you enabled RTTI in the compiler options?

--
Maxim Yegorushkin
Jul 22 '05 #3

P: n/a
> I am trying to find a way to eliminate vararg functions from my code
by packaging the input parameters in stringstreams. Here is an
oversimplified example of what I am trying to do:
Functions FUNC1 and FUNC2 delegate to functions func1 and func2,
respectively. The goal is to delegate to func1 and func2 using an
identical interface provided by the template function
template<typename F>FTEMPL that takes a stringstream as input and
determines which function to delegate by determining the type of the
generic parameter, F. Here is the code (previously I had a vararg
function instead of the template function):

#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo.h>


<typeinfo.h>??? No such Standard Header exists.

-- --
Abstraction is selective ignorance.
-Andrew Koenig
-- --
Jul 22 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.