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

read file, execute functions

P: n/a

I'm perusing a question and curiosity got the best of me in part
because I cant solve the problem

Consider:

typedef unsigned int word_type ;
class foo {

public:
void set_mx_digits_1 ( word_type wt ) {}
void set_mx_digits_2 ( double dt ) { }
// lots more.
};

Within a file, you're given a typedef'd representation of the foo
functions and the input arguments to the functions. In other words:

// filename input_file.dat
typedef void ( foo::*set_mx_digits_1 )( word_type wt ), 15
typedef void ( foo::*set_mx_digits_2 )( double dt ), 3.6
// lots more

The goal is to read the contents of the file into an appropriate
container then invoke the member functions with the input arguments.
Now I could read the contents into a string and convert the numbers
from string to int, string to double etc, but how could one store the
typedef'd representation into a map without manual intervention ( I'm
not seeing a way to read a file and store function pointers in a
map ..to compound things the input arguments are different) is beyond
me.

Maybe I misunderstood, however, if a solution exists I'd like to see
it because I'm coming up short. Thanks in advance.
Nov 16 '08 #1
Share this Question
Share on Google+
6 Replies


P: n/a
On 2008-11-16 03:19, ma740988 wrote:
I'm perusing a question and curiosity got the best of me in part
because I cant solve the problem

Consider:

typedef unsigned int word_type ;
class foo {

public:
void set_mx_digits_1 ( word_type wt ) {}
void set_mx_digits_2 ( double dt ) { }
// lots more.
};

Within a file, you're given a typedef'd representation of the foo
functions and the input arguments to the functions. In other words:

// filename input_file.dat
typedef void ( foo::*set_mx_digits_1 )( word_type wt ), 15
typedef void ( foo::*set_mx_digits_2 )( double dt ), 3.6
// lots more

The goal is to read the contents of the file into an appropriate
container then invoke the member functions with the input arguments.
Now I could read the contents into a string and convert the numbers
from string to int, string to double etc, but how could one store the
typedef'd representation into a map without manual intervention ( I'm
not seeing a way to read a file and store function pointers in a
map ..to compound things the input arguments are different) is beyond
me.
You have to create a map from the typedef (or some for of it) as a
string to a member-function pointer and then fill the map when the
program starts. Then read the line from the input-file, look it up in
the map, and use the member-function pointer to invoke the function.

What you really want is probably reflection, which is not possible in
standard C++.

--
Erik Wikström
Nov 16 '08 #2

P: n/a
On Nov 16, 6:48*am, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2008-11-16 03:19, ma740988 wrote:
I'm perusing a question and curiosity got the best of me in part
because I cant solve the problem
Consider:
typedef unsigned int word_type ;
class foo {
public:
* void set_mx_digits_1 ( word_type wt ) {}
* void set_mx_digits_2 ( double dt ) { }
* // lots more.
};
Within a file, you're given a typedef'd representation of the foo
functions and the input arguments to the functions. *In other words:
* // filename input_file.dat
* typedef void ( foo::*set_mx_digits_1 )( word_type wt ), 15
* typedef void ( foo::*set_mx_digits_2 )( double dt ), 3.6
* // lots more
The goal is to read the contents of the file into an appropriate
container then invoke the member functions with the input arguments.
Now I could read the contents into a string and convert the numbers
from string to int, string to double etc, but how could one store the
typedef'd representation into a map without manual intervention ( I'm
not seeing a way to read a file and store function pointers in a
map ..to compound things the input arguments are different) is beyond
me.

You have to create a map from the typedef (or some for of it) as a
string to a member-function pointer and then fill the map when the
program starts. Then read the line from the input-file, look it up in
the map, and use the member-function pointer to invoke the function.
I think I'm following you. The key is essentially a string and the
value a function pointer. Correct?
Follow on question for you. There's 60 'set_WHATEVER* (WHATEVER could
be header_word, hex_digits_1, tgt_north etc. etc. etc.)' methods with
arguments double or unsigned int (word_type). Is it possible to have
templated arguments to function pointers? If how could you provide
source illustrating this. I'd like to believe I could have a generic
function pointer inside .. say a map or some appropriate container.
That function then will call the appropriate set_WHATEVER method.

What you really want is probably reflection, which is not possible in
standard C++.
I see.

Nov 16 '08 #3

P: n/a
On 2008-11-16 17:47, ma740988 wrote:
On Nov 16, 6:48 am, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2008-11-16 03:19, ma740988 wrote:
I'm perusing a question and curiosity got the best of me in part
because I cant solve the problem
Consider:
typedef unsigned int word_type ;
class foo {
public:
void set_mx_digits_1 ( word_type wt ) {}
void set_mx_digits_2 ( double dt ) { }
// lots more.
};
Within a file, you're given a typedef'd representation of the foo
functions and the input arguments to the functions. In other words:
// filename input_file.dat
typedef void ( foo::*set_mx_digits_1 )( word_type wt ), 15
typedef void ( foo::*set_mx_digits_2 )( double dt ), 3.6
// lots more
The goal is to read the contents of the file into an appropriate
container then invoke the member functions with the input arguments.
Now I could read the contents into a string and convert the numbers
from string to int, string to double etc, but how could one store the
typedef'd representation into a map without manual intervention ( I'm
not seeing a way to read a file and store function pointers in a
map ..to compound things the input arguments are different) is beyond
me.

You have to create a map from the typedef (or some for of it) as a
string to a member-function pointer and then fill the map when the
program starts. Then read the line from the input-file, look it up in
the map, and use the member-function pointer to invoke the function.

I think I'm following you. The key is essentially a string and the
value a function pointer. Correct?
Follow on question for you. There's 60 'set_WHATEVER* (WHATEVER could
be header_word, hex_digits_1, tgt_north etc. etc. etc.)' methods with
arguments double or unsigned int (word_type). Is it possible to have
templated arguments to function pointers? If how could you provide
source illustrating this. I'd like to believe I could have a generic
function pointer inside .. say a map or some appropriate container.
That function then will call the appropriate set_WHATEVER method.
You can probably not have just one map, since the values in a map all
have to have the same type, so you need one map for each combination of
parameter types.

You could probably use some kind of wrapper-class which container
several function-pointers and only initialise the correct one and use
that as the value, but I'm not sure if that's a good solution.

--
Erik Wikström
Nov 16 '08 #4

P: n/a
Ypu would be better off by directly calling
the member functions by reading the file, or by storing the read strings
to call them later.
The latter I understand, the former - "You would be better off by
directly calling the member functions by reading the file" - I'm not
following. I understanding reading and storing a string then invoking
the member functions. I'm not understanding how I could read a file
then invoke the member functions directly.
Worse case show me an example in source.

Thanks

Nov 17 '08 #5

P: n/a
ma740988 <ma******@gmail.comkirjutas:
>Ypu would be better off by directly calling
the member functions by reading the file, or by storing the read
strings
>to call them later.

The latter I understand, the former - "You would be better off by
directly calling the member functions by reading the file" - I'm not
following. I understanding reading and storing a string then invoking
the member functions. I'm not understanding how I could read a file
then invoke the member functions directly.
Worse case show me an example in source.
Here you are, it got a bit longer than I thought, and the parser is not
very smart, and error handling is lacking, and this most probably is not
what you want, but anyway, I figure as I already wrote this for fun, I
can as well post it. (Tested by cygwin g++ 3.4.4.)

Cheers, Paavo

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>

typedef std::string::size_type indx_t;

typedef unsigned int word_type ;
class foo {

public:
void set_mx_digits_1 ( word_type wt ) {
std::cout << "set_mx_digits_1(" << wt << ") called\n";
}
void set_mx_digits_2 ( double dt ) {
std::cout << "set_mx_digits_2(" << dt << ") called\n";
}
// lots more.
};

std::string FindFuncName(const std::string& buffer) {
indx_t k = buffer.find("foo::*");
if (k==buffer.npos) return "";
k += strlen("foo::*");
k = buffer.find_first_not_of(" \t", k);
if (k==buffer.npos) return "";
indx_t l = buffer.find_first_of(" \t)", k);
if (l==buffer.npos) return "";
return buffer.substr(k, l-k);
}

std::string FindArgType(const std::string& buffer) {
indx_t k = buffer.rfind("(");
if (k==buffer.npos) return "";
++k;
k = buffer.find_first_not_of(" \t", k);
if (k==buffer.npos) return "";
indx_t l = buffer.find_first_of(" \t)", k);
if (l==buffer.npos) return "";
return buffer.substr(k, l-k);
}

std::string FindArgument(const std::string& buffer) {
indx_t k = buffer.rfind(",");
if (k==buffer.npos) return "";
++k;
k = buffer.find_first_not_of(" \t", k);
if (k==buffer.npos) return "";
return buffer.substr(k);
}
// Something to silence compiler warnings and errors on invalid
// function and argument combinations.
template<typename TT ConvertForDigits1(T x) {return x;}
int ConvertForDigits1(double x) {/* should be never called*/ return 0;}

template<typename TT ConvertForDigits2(T x) {return x;}

template<typename T>
void CallMemberFunc(const std::string& funcname, const std::string&
argstring, foo& myfoo) {
std::istringstream argstream(argstring);
T arg1;
if (argstream >arg1) {
if (funcname=="set_mx_digits_1") {
myfoo.set_mx_digits_1(ConvertForDigits1(arg1));
} else if (funcname=="set_mx_digits_2") {
myfoo.set_mx_digits_2(ConvertForDigits2(arg1));
} // lots more
}
}

void ReadParseAndExecute(const std::string& filename, foo& myfoo) {
std::ifstream is(filename.c_str());
std::string buffer;
while(std::getline(is, buffer)) {

// Parse the input line
std::string funcname = FindFuncName(buffer);
std::string argstring = FindArgument(buffer);
std::string argtype = FindArgType(buffer);

// dispatch to template according to argument type
if (argtype=="word_type") {
CallMemberFunc<word_type>(funcname, argstring, myfoo);
} else if (argtype=="double") {
CallMemberFunc<double>(funcname, argstring, myfoo);
} // some more
}
}

int main() {

{
// Prepare an example file
std::ofstream os("input_file.dat");
os <<
"typedef void ( foo::*set_mx_digits_1 )( word_type wt ), 15\n";
os <<
"typedef void ( foo::*set_mx_digits_2 )( double dt ), 3.6\n";
}
foo myfoo;
ReadParseAndExecute("input_file.dat", myfoo);
}
Nov 17 '08 #6

P: n/a
int main() {

* * * * {
* * * * * * * * // Prepare an example file
* * * * * * * * std::ofstream os("input_file.dat");
* * * * * * * * os <<
* * * * * *"typedef void ( foo::*set_mx_digits_1 )( word_typewt ), 15\n";
* * * * * * * * os <<
* * * * * *"typedef void ( foo::*set_mx_digits_2 )( double dt), 3.6\n";
* * * * }

* * * * foo myfoo;
* * * * ReadParseAndExecute("input_file.dat", myfoo);

}
You cleared up my confusion. Thanks

Nov 17 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.