It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
There is in Qt such functionality: QMetaObject::invokeMethod(QObject * obj, const char * member, ...), which invokes method from string (member). How can I do the same (or similar)? Thanks)
You can't do this in pure c++, but you can read about reflection/introspect in c++ in this question
A similar thing can be achieved with a map<std::string, std::function<void()>>:
std::map<std::string, std::function<void()>> funs;
funs["hello world"] = [] () { std::cout << "hello world"; };
funs["hello world"]();
The question is how similar do you want it? How "native" should the call look like?. You can do things like:
void foobar(int, float);
...
invoke("foobar", 5, 5.f);
but the implementation looks hacky and is non-trivial.
There is a related problem:
You can get pretty far with variadic templates and some template/virtual techniques. With the following codes, you'll be able to do something like:
std::string select_string (bool cond, std::string a, std::string b) {
return cond ? a : b;
}
int main () {
Registry reg;
reg.set ("select_it", select_string);
reg.invoke ("select_it", "1 John Wayne"));
reg.invoke ("select_it", "0 John Wayne"));
}
i.e. where the argument list is dissected into a real argument list for a native function call. With variadic templates you can do a lot of things; I am not sure if you should.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 months ago.
Improve this question
EDIT: I was being dumb. The functionMaker call is shockingly a function not a constructor, so the braces obviously don't work.
So I have what is basically a factory function for producing a std::function from int to int, a quick minimal example is
std::function<int(int)> functionMaker(int x) {
return [x](int foo){return foo*x;};
}
Basically, I want to bind some values into the function (kind of like currying), and then call it later.
I want to use it through something like
functionMaker{2}(10)
But it errors me.
I verified that
functionMaker(2)(10)
works
And I explored what happens if I stored the function and then called it.
auto fct = functionMaker{2};
std::cout << fct(10) << std::endl;
fails, but
auto fct = functionMaker(2);
std::cout << fct(10) << std::endl;
works.
So it seems like braces just don't work here. What's going on? To reiterate, I would like to call it with something like functionMaker{2}(10). This way it's a bit easier for me to read which part is the construction and which part is the calling. What am I missing here?
If you'd like functionMaker{} to work, then functionMaker needs to be a class/struct. Functions can only take arguments via (). However, it's relatively easy to make it a class:
struct functionMaker
{
functionMaker(int x)
: f([x](int foo){return foo*x; }) {}
int operator()(int foo) { return f(foo); }
std::function<int(int)> f;
};
It's a bit more clumsy, but you only need to write it once; you can even generalize it to be like, make_functionMaker(f, ...).
Note that you can save std::function's overhead by simply implementing the function in operator().
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Based on the comments i ve changed the subject to proc code and i
withdraw the claim that it is C++ syntax. Keeping the tags same; as i
still hope it is similar to c++ and no ProC tag available please bear
with it.
I suppose its a very new bee question. But as i have no ample time to learn C++ documentation i would appreciate if i can get help on this.
I am working on converting pro*C code which resembles C++ syntax.
Here is the code snippet
#include <stdio.h>
#include <string.h>
#include <prg_codes.h>
#include <prg_defines.h>
typedef struct
{
int errorflag;
int slot;
} option_info;
int calc_options(currArgc,currArgv,options)
int currArgc;
char *currArgv[];
option_info *options;
{
int optChar;
int invopt=0;
while ((optChar = getopt(currArgc, currArgv, ":s:")) != -1 && !(invopt))
{}
/* other commands */
}
void main(int argc, char *argv[])
{
option_info options;
int rc = 0;
rc=calc_options(argc,argv,&options);
/* other commands */
}
My question is
option_info is defined as a struct then as a function and called from main. Is it fine? how does it work?
Is option_info inside the function calc_options. Because option_info seems using the parameters defined in calc_options.
Or calc_options body is written somewhere else in any other file in the include section ?
This snippet is in the archaic K&R C syntax which predates ANSI C. Then it is indented strangely which makes it look at first glance like you describe, but it really isn't. calc_options is the function definition with three arguments, the 3rd of which is a pointer options to typedef option_info.
This is the same thing in ANSI C syntax, so it is easier to read:
int calc_options(int currArgc, char *currArgv[], option_info *options)
{
int optChar;
int invopt=0;
while ((optChar = getopt(currArgc, currArgv, ":s:")) != -1 && !(invopt))
{}
/* other commands */
}
"option_info is defined as a struct" Yes (well a typedef to a struct)
"then as a function and called from main". No
"Is it fine?" Yes (but should be changed to ANSI syntax)
"how does it work?" Pretty good
"Is option_info inside the function calc_options?" It is the type of the 3rd argument options
"Because option_info seems using the parameters defined in calc_options." It is the type of parameter options
"Or calc_options body is written somewhere else in any other file in the include section ?" Nope
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have a class that will provide a function with an item seen which will return false the first time it's seen with a certain string, but true every time after that when the same string is called.
class Tracking
{
...
public:
bool itemseen(const char* str)
{
..
}
};
It sounds like you need/want either an std::set<std::string> or an std::unordered_set<std::string>.
When you receive an item, attempt to insert it into the [unordered_]set. Check the return value to see if that succeeded or not.
Note that searching for the item first, then attempting to insert if it's not present is fairly wasteful. You normally just want to attempt to insert it, and then check the return value to see if that succeeded:
class whatever {
std::set<std::string> strings;
public:
bool itemseen(std::string const &input) {
return !strings.insert(input).second;
}
};
If you do a search and then insert, you're forcing it to search the collection twice when/if it inserts a new object. Using the return value instead allows you to do the search only once. IOW, you can expect it to be roughly twice as fast (though caching is likely to make the second search faster, so the measured difference may be smaller than that).
Simplest way is by using STL:
#include <set>
#include <string>
std::set<std::string> seen;
bool itemseen(const char* str)
{
if (seen.find(str) == seen.end())
{
seen.insert(str);
return false;
}
return true;
}
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Ok, so it's been a while since I wrote anything big in c++ and I've grown used to some of the niceties of more modern languages. This is one that's been nagging at me and I'm sure there's an answer out there. Is there any way to call a function specified as a string by a user at run-time? Without having to resort to some sort of massive switch/if block?
The situation I'm in boils down to this: I've got a whole whack-load of math-related problems I've solved in C++ and specified as "Problem1.cpp/Problem1.h", "Problem2.cpp/Problem2.h", etc. Each problem has a function called problemX() (where X is the number of the problem) that kicks off the solution.
At the start of the program I'd like to ask the user "Which problem would you like to solve?" and they'd specify a number. I'd then like to call the appropriate problemX() function without having to resort a massive hard coded switch statement (or an if statement, or an indexed array of function pointers, etc).
I'm sure this has got to be possible, but I just can't remember how to go about it. Any ideas?
unordered_map of strings to function pointers.
Tweak the user input to ensure it is all lower case (or upper IF YOU LIKE SHOUTING), then just lookup the function. If it exists call it, else error.
C++ has no automatic compile or run time reflection of its code in the language. Many library frameworks do have run time reflection of the symbols in a library.
So solution 1:
Stick your problems into their own dynamic libraries, and have the main program dynamically load them and look up the symbol names they export.
Solution 2:
Replace your raw C-style functions with named objects. So you might have:
class Problem;
void RegisterProblem( std::string name, Problem const* problem );
std::map< std::string, Problem const* >& GetProblems();
class Problem
{
protected:
Problem( std::string name ): RegisterProblem( std::move(name), this ) {}
virtual void operator() const = 0;
virtual ~Problem() {}
};
class Problem1: public Problem
{
public:
Problem1():Problem("Problem1") {}
virtual void operator() const { /* implementation */ }
};
// in .cpp file:
Problem1 problem1Instance();
void RegisterProblem( std::string name, Problem const* problem )
{
GetProblems()[name] = problem;
}
std::map< std::string, Problem const* >& GetProblems()
{
static std::map< std::string, Problem const* > problemMap;
return problemMap;
}
int main()
{
// parse user input to get this string:
std::string testInput = "Problem1";
// run the problem determined by testInput:
Problem* prob = GetProblems()[testInput];
Assert(prob);
(*prob)();
}
Above we have some horribly written spew of code that has self-registering Problems (who register in a static map), and a main() that executes whatever problem the string specifies.
A way I think would be cleaner is:
// In RegisterProblem.h:
// these two have obvious implementations:
std::map< std::string, std::function<void()> >& GetProblems();
bool RegisterProblem( std::string s, std::function<void()> ); // always returns true
// In problem1.cpp:
void Problem1(); // implement this!
bool bProblem1Registered = RegisterProblem( "Problem1", Problem1 );
// In problem2.cpp:
void Problem2(); // implement this!
bool bProblem2Registered = RegisterProblem( "Problem2", Problem2 );
// etc
// in main.cpp:
int main(int argc, char** argv)
{
if (argc == 0)
return -1; // and maybe print help
auto it = GetProblems().find( argv[1] );
if (it == GetProblems().end())
return -1; // and maybe print help
it->second(); // call the problem
}
where we do away with the needless class hierarchy and just maintain a map between string and void() functions. The maintenance of this map is distributed to each place where the functions are written, so there is no central list or if statement.
I wouldn't ship anything with code as crude as the above, but I hope you get the idea.
You should use an std::map<std::string,_function_pointer_defined_by_you> to store the names of the functions as keys, and the function pointers as values. You could also use an std::unordered_map<std::string,_function_pointer_defined_by_you>, which is something like std::hash_map. If you can use C++11, you will find the std::unordered_map at the header file <unordered_map>, and if you can't at <tr1/unordered_map>. Documentation about both map, and unordered_map can be found at:
http://cplusplus.com/reference/stl/map/
http://cplusplus.com/reference/stl/unordered_map/
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have little knowlage in C++
so I have this code
bool is_successful = true;
ex_file_licensing exFileLicence;
std::string flexLMfilePath;
flexLMfilePath.append("C:/Desktop/QA-program/testsuite/tmp/");
std::string Message = exFileLicence.checkLicense(DI_MF,flexfilePath,is_successful);
and I was asked to move it outside the main and then call it in the main
and now I have no idea what to do
Could you please tell me what are the steps that I should follow
please be as specific as possible, I'm really bad at this thing
Thanks
You must create a function and call that function inside main:
void foo(); //this is called a function prototype
main()
{
...
foo() //your function in place of that code
}
void foo()
{
...//the code originally in main. This is called your function definition
}
this is how creating functions works and is basically how any code in c++ is written. Sometimes the functions appear in files outside the main file but its basically the same.
Check out C++ Functions. I'm assuming you have something as follows.
int main(){
//***your stuff
return
You need the following.
void function(){
//**your stuff
return;
}
int main(){
function();
return;
}
When the program starts it will automatically go to main and when it reaches the call:
function();
It will pass control to the code wrapped within
void function(){
return;
}
If I understand correctly I think you just need to put the code in a function, like this:
void CodeFunction()
{
bool is_successful = true;
ex_file_licensing exFileLicence;
std::string flexLMfilePath;
flexLMfilePath.append("C:/Desktop/QA-program/testsuite/tmp/");
std::string Message = exFileLicence.checkLicense(DI_MF,flexfilePath,is_successful);
}
and you can then call it from main by using CodeFunction().
Remember to put this above the main function, or if it's below declare it above main using
void CodeFunction();
Hope this helps.
You need to write a function, move the code to the function and then call the function from main - http://www.cplusplus.com/doc/tutorial/functions/