I think the problem is pretty common. You have some input string, and have to call a function depending on the content of the string. Something like a switch() for strings.
Think of command line options.
Currently I am using:
using std::string;
void Myclass::dispatch(string cmd, string args) {
if (cmd == "foo")
cmd_foo(args);
else if (cmd == "bar")
cmd_bar(args);
else if ...
...
else
cmd_default(args);
}
void Myclass::cmd_foo(string args) {
...
}
void Myclass::cmd_bar(string args) {
...
}
and in the header
class Myclass {
void cmd_bar(string args);
void cmd_foo(string args);
}
So every foo and bar I have to repeat four (4!) times. I know I can feed the function pointers and strings to an static array before and do the dispatching in a loop, saving some if...else lines. But is there some macro trickery (or preprocessor abuse, depending on the POV), which makes is possible to somehow define the function and at the same time have it update the array automagically?
So I would have to write it only twice, or possibly once if used inline?
I am looking for a solution in C or C++.
It sounds like you're looking for the Command pattern
Something like this:
Create a map like this
std::map<std::string, Command*> myMap;
then just use your key to execute the command like this....
std::map<std::string, Command*>::iterator it = myMap.find(str);
if( it != myMap.end() ) {
it->second->execute()
}
To register your commands you just do this
myMap["foo"] = new CommandFoo("someArgument");
myMap["bar"] = new CommandBar("anotherArgument");
The basic solution, per my link in the question comment, is to map a string to a function call of some sort.
To actually register the string -> function pointer/functor pair:
Firstly, have a singleton (shock! horror!) dispatcher object.
Let's call it TheDispatcher - it's a wrapper for a map<string,Func>, where
Func is your function pointer or functor type.
Then, have a register class:
struct Register {
Register( comst string & s, Func f ) {
TheDispatcher.Add( s, f );
}
};
Now in your individual compilation units you create
static objects (shock! horror!):
Register r1_( "hello", DoSayHello );
These objects will be created (assuming the code is not in a static library) and will automatically register with TheDispatcher.
And at run-time, you look up strings in TheDispatcher and execute the associated function/functor.
as alternative to the Command pattern you can build an hashtable of string -> function pointers:
typedef void (*cmd)(string);
The ugly macro solution, which you kind-of asked for. Note that it doesn't automatically register, but it does keep some things synchronized, and also will cause compile errors if you only add to mappings, and not the function in the source file.
Mappings.h:
// Note: no fileguard
// The first is the text string of the command,
// the second is the function to be called,
// the third is the description.
UGLY_SUCKER( "foo", cmd_foo, "Utilize foo." );
UGLY_SUCKER( "bar", cmd_bar, "Turn on bar." );
Parser.h:
class Myclass {
...
protected:
// The command functions
#define UGLY_SUCKER( a, b, c ) void b( args )
#include Mappings.h
#undef UGLY_SUCKER
};
Parser.cpp:
void Myclass::dispatch(string cmd, string args) {
if (cmd == "")
// handle empty case
#define UGLY_SUCKER( a, b, c ) else if (cmd == a) b( args )
#include Mappings.h
#undef UGLY_SUCKER
else
cmd_default(args);
}
void Myclass::printOptions() {
#define UGLY_SUCKER( a, b, c ) std::cout << a << \t << c << std::endl
#include Mappings.h
#undef UGLY_SUCKER
}
void Myclass::cmd_foo(string args) {
...
}
You'll have to at least define the functions and add them to some registry. (If they are to be non-inline member functions of some class, you'll also have to declare them.) Other than some domain-specific language generating the actual code (like cjhuitt's macro hackery), I see no way around mentioning these functions two (or three) times.
Related
I am trying to print IT SUCCESS\nET SUCCESS\n using following code but it's failing in compilation with error error: ‘printds’ was not declared in this scope which I know is because it's taking macro input as ds literal. Does anyone know how to do this? The use case is that there are several printXX() functions which should be called based on value passed in macro.
#include <stdio.h>
#define FOO(val) { \
print ## val(); \
}
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
int main() {
const char* ds = "IT", es = "ET";
FOO(ds); FOO(es);
return 0;
}
You can change
FOO(ds); FOO(es);
to
FOO(IT); FOO(ET);
Because macro substitutions happen before your code is compiled.
But you can define a function called FOO like
#include <stdio.h>
#include <iostream>
using namespace std;
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
void FOO(const string str)
{
if(str=="IT")
printIT();
else
printET();
}
int main()
{
const char* ds = "IT",*es="ET";
FOO(ds);FOO(es);
return 0;
}
it's taking macro input as ds literal.
Yes, that's to be expected. Preprocessor macros are expanded at compile time. The arguments to function-like macros are the literal source-code tokens that appear between the parentheses in the macro invocation. These have no additional meaning to the preprocessor.
Does anyone know how to do this? The use case is that there are several printXX() functions which should be called based on value passed in macro.
Again, macros are expanded, to source code (approximately), at compile time. The process does not and cannot take into account C++ runtime semantics such as converting variables' identifiers into corresponding values.
If runtime dynamic function dispatch based on variables' values is what you're after then you need an altogether different mechanism. You could use ordinary conditional statements to select between different function calls, for example. If you wanted to be even more dynamic then you could consider preparing a lookup table of function pointers, and using that to select and call appropriate functions.
In comments, you added
I've several methods queryServers, queryNodes, queryTargets which I want to call using above trick.
You may be able to accomplish something similar to what you ask via templates or overloaded functions. These mechanisms, too, operate at compile time, so they have no access to runtime information such as variables' values, but they do know about and rely upon C++ data types.
Alternatively, perhaps you're looking for the Strategy pattern.
The first thing you need to know is that the Macros are preprocessor directives which are a fragment of code with a given name. if you use macro name in your program it will replace that code fragment into that place you use the macro name at compile time first stage called Pre-processing stage.
#include <stdio.h>
#define FOO(val) { \
print ## val(); \
}
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
int main() {
const char* ds = "IT", es = "ET";
FOO(ds); FOO(es);
return 0;
}
In your code, you try to input ds and es variables into FOO function like macro. But ds and es variables declared in program stack only when you run the program. At the compile-time, it just treats them as only texts. Therefore macro function input it takes as text ds and es and replaced with val. That's why you got the compile time error. The following code fragment I have changed is working as you expected.
#include <stdio.h>
#define FOO(val) { \
print ## val(); \
}
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
int main() {
const char* ds = "IT", *es = "ET";
FOO(IT); FOO(ET);
return 0;
}
If you are interested you can find more about Macros in the following resources.
GCC online documentation and Article about Macros . Also, you can view the preprocessed code using g++ -E (your cpp file name). Thanks.
Possible solution without MACRO:
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
void foo(std::string_view s)
{
static const std::map<std::string_view, void(*)()> funcs{
{"IT", &printIT},
{"ET", &printET}
};
auto it = funcs.find(s);
if (it != funcs.end()) {
(*it->second)();
}
}
int main() {
const char* ds = "IT";
const char* es = "ET";
foo(ds); foo(es);
}
Demo
I was just experimenting with C++. I was trying to write a small macro so that all the functions that I define are automatically stored in a map so that I can query, at run time, what functions exist and run them too. The code is as follows:
#include <map>
using namespace std;
typedef void (*funcPointer)();
map <char*, funcPointer> funcList;
#define Function(x) void x() { funcList[#x] = x;
#define End }
I was used funcPointer and End only for easy readability and implementation. Now, I can define a function as
Function(helloWorld)
cout << "Hello World";
End
Now, to read the function names as a list and run all the functions, I use the following code:
int main() {
//helloWorld();
for (map<char*, funcPointer>::iterator I = funcList.begin(); I != funcList.end(); I++) {
printf(I->first);
I->second();
}
getchar();
return 0;
}
The problem is, if I keep the first line of main() (helloWorld();) commented, the compiler doesn't compile the function and skips it for optimization, as according to the compiler, it is never used. So, the function list turns up empty. If, instead, I call the function once, every thing works perfectly, except that it prints "Hello World" twice. Also, I wrote the macro specifically so I do not have to do that.
So, is there any way that I can force the compiler to compile a function even if it is not used?
The problem is that the code to register the function is inside the function, so won't happen unless you call the function. You might instead register it by initialising a global variable, which will happen automatically before main begins. This might look something like
struct funcRegistration {
funcRegistration(char * name, funcPointer func) {funcList[name] = func;}
};
#define Function(x) \
void x(); \
funcRegistration x##_registration(#x, x); \
void x() {
The compiler compiles the function, however your map won't be populated unless its called.
Because funcList[#x] = x; comes inside the function block { } after macro expansion.
I'm wrapping the Windows API, and I wish to make error checking easy to use, and helpful. Currently, I have a global error object, with a function set to handle a new error. The set function takes four arguments: bool Error::set (const int code, const char * file, const char * const function, const int line); The function uses the file, function, and line arguments to display them in a nicely formatted message.
To ease the setting of errors, there is a macro #define setError() error.set (GetLastError(), __FILE__, __FUNCTION__, __LINE__); This way I'm able to use setError() at any time to respond to an error that an API function has set by adding it after I call that API function.
Unfortunately, this causes the code to look something like this:
SomeAPIFunction();
setError();
AnotherAPIFunction();
setError();
There is also a problem with constructors:
MyClass:MyClass()
: a (SomeAPIFunction), b (AnotherAPIFunction)
{
setError(); //what if both functions set an error?
}
As you can see, by using member initializer syntax, I'm actually limiting myself.
One way to fix this would be to wrap every API function:
int someAPIFunction()
{
int ret = SomeAPIFunction();
setError();
return ret;
}
The function portion of the error message would tell me which function originated the error. Of course, that has to be the worst possible way of dealing with this.
The solution, it seems, is to use variadic templates. The problem is, I have no idea what I'm supposed to be doing to get them working for this. I'd imagine the final code looks something like one of the following:
wrap<int, SomeAPIFunction (5)>();
wrap<int, SomeAPIFunction, 5>();
wrap<int, SomeAPIFunction> (5);
I've read things on beginning variadic templates, but they've all left me clueless of how to set up something like this. Could anyone point me in the right direction?
I found the following on a similar question:
#include <iostream>
template<void f(void)>
struct Wrap {
void operator()() const {
std::cout << "Pre call hook" << std::endl;
f();
}
};
namespace {
void test_func() {
std::cout << "Real function" << std::endl;
}
}
const Wrap<&test_func> wrapped_test_func = {};
int main() {
wrapped_test_func();
return 0;
}
The respondent noted that variadic templates would be a necessity to make this generic enough. It's a start, but I'm lost and grateful of any help on the matter.
I think you'll be able to make it work with this syntax:
wrap(&SomeAPIFunction, arg1, arg2);
The key is to let the compiler use type deduction to determine the template type parameters, since they get pretty messy in a hurry.
The code should look something like:
template<typename TRet, typename... TArgs>
TRet wrap( TRet(WINAPI *api)(TArgs...), TArgs... args )
{
return api(args...);
}
Naturally, you'll want to use a macro to hide the address-of-function operator, use stringizing to store the function name, and store the filename and line number also, passing all of that to the actual variadic function. You'll need variadic macros for that. In fact, could you do all of this just with variadic macros and no templates?
I have a logger class. Call it MyLogger. I may use it in a function like this:
void MyFunc(MyLogger& oLogger)
{
//Do stuff
oLogger.Log("In MyFunc : Some Error");
//Do something else
oLogger.Log("In MyFunc : Some other error");
}
Now, I want to prepend "In MyFunc" to the logs if the log comes from inside MyFunc. Similarly for other functions...
Because this is tiresome, I tried something like this:
void MyLogger::PushPrependString(const char*)
{
//Store prepend string in stack and set it as current prepend string.
}
void MyLogger::PopPrependString()
{
//Pop the most recent prepend string.
}
Now, I can use these two functions like this:
void MyFunc(MyLogger& oLogger)
{
oLogger.PushPrependString("In MyFunc : ");
//Do stuff
oLogger.Log("Some Error");
//Do something else
oLogger.Log("Some other error");
oLogger.PopPrependString();
}
The trouble is, if there are multiple returns in a function, this becomes ugly. Is there any way around this? Is this a common problem? Is there any preprocessor macro like __FILE__ or __LINE__ for getting the name of the function a line appears in? Any comments would be appreciated. Thanks.
"The trouble is, if there are multiple returns in a function, this becomes ugly. Is there any way around this?"
Yes, just use an object with constructor (calls PushPrependString) and destructor (calls PopPrependString).
class LogPrefix
{
private:
MyLogger* logger_;
LogPrefix( LogPrefix const& ); // No such.
LogPrefix& operator=( LogPrefix const& ); // No such.
public:
LogPrefix( MyLogger& logger, char const s[] )
: logger_( &logger )
{
logger_->PushPrependString( s );
}
~LogPrefix()
{
logger_->PopPrependString();
}
};
Disclaimer: off the cuff code, not touched by compiler's hands...
"Is this a common problem?"
Yes.
"Is there any preprocessor macro like FILE or LINE for getting the name of the function a line appears in?"
Not in C++98. Various compilers offer various extensions that do that. IIRC C++0x adopts the C99 scheme, which unfortunately just provides static strings.
Cheers & hth.
RAII - Resource Acquisition Is Initialization.
In this case, you create an object on entry to the function that identifies the current function to the logging system; when the function exits (by any return or by exception thrown or by exception not caught), the object will be destroyed, and the destructor changes what is printed in future by the logging system.
In C99, and maybe in some C++ compilers such as G++, there is a predefined variable, __func__ containing the function name. The C++ equivalent is more complex, I believe.
I want your suggestion on the following pseudo-code. Please suggest how could I improve it, whether or not I could use some design patterns.
// i'm receiving a string containing : id operation arguments
data = read(socket);
tokens = tokenize(data," "); // tokenize the string based on spaces
if(tokens[0] == "A") {
if(tokens[1] == "some_operation") {
// here goes code for some_operation , will use the remaining tokens as arguments for function calls
}
else if(tokens[1] == "some_other_operation") {
// here goes code for some_other_operation , will use the remaining tokens
}
...
else {
// unknown operation
}
}
else if(tokens[0] == "B") {
if(tokens[1] == "some_operation_for_B") {
// do some operation for B
}
else if(tokens[1] == "yet_another_operation") {
// do yet_another_operation for B
}
...
else {
// unknown operation
}
}
I hope you get the point . The thing is I have a large number of id's and each has it's own operations , and I think it's kinda ugly to have 10 screens of code containing a lot of if's and else if's.
Have a class for each ID which implements a common interface. Basically the Strategy pattern IIRC.
So you'd call (pseudo)code like:
StrategyFactory.GetStrategy(tokens[0]).parse(tokens[1..n])
First write down the syntax of what you support, then write the code to support it.
Using BNF notation is great for that. And using the Spirit library for the code-part is quite straightforward.
Command := ACommand | BCommand
ACommand := 'A' AOperation
AOperation := 'some_operation' | 'some_other_operation'
BCommand := 'B' BOperation
BOperation := 'some_operation_for_B' | 'some_other_operation_for_B'
This easily translates into a Spirit parser. Every production rule would become a one-liner, every end-symbol would be translated into a function.
#include "stdafx.h"
#include <boost/spirit/core.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost::spirit;
namespace {
void AOperation(char const*, char const*) { cout << "AOperation\n"; }
void AOtherOperation(char const*, char const*) { cout << "AOtherOperation\n"; }
void BOperation(char const*, char const*) { cout << "BOperation\n"; }
void BOtherOperation(char const*, char const*) { cout << "BOtherOperation\n"; }
}
struct arguments : public grammar<arguments>
{
template <typename ScannerT>
struct definition
{
definition(arguments const& /*self*/)
{
command
= acommand | bcommand;
acommand = chlit<char>('A')
>> ( a_someoperation | a_someotheroperation );
a_someoperation = str_p( "some_operation" ) [ &AOperation ];
a_someotheroperation = str_p( "some_other_operation" )[ &AOtherOperation ];
bcommand = chlit<char>('B')
>> ( b_someoperation | b_someotheroperation );
b_someoperation = str_p( "some_operation_for_B" ) [ &BOperation ];
b_someotheroperation = str_p( "some_other_operation_for_B" )[ &BOtherOperation ];
}
rule<ScannerT> command;
rule<ScannerT> acommand, bcommand;
rule<ScannerT> a_someoperation, a_someotheroperation;
rule<ScannerT> b_someoperation, b_someotheroperation;
rule<ScannerT> const&
start() const { return command; }
};
};
template<typename parse_info >
bool test( parse_info pi ) {
if( pi.full ) {
cout << "success" << endl;
return true;
} else {
cout << "fail" << endl;
return false;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
arguments args;
test( parse( "A some_operation", args, space_p ) );
test( parse( "A some_other_operation", args, space_p ) );
test( parse( "B some_operation_for_B", args, space_p ) );
test( parse( "B some_other_operation_for_B", args, space_p ) );
test( parse( "A some_other_operation_for_B", args, space_p ) );
return 0;
}
You could have a look into "Table Driven Methods" (as described in "Code Complete", 2nd edition, chapter 18).
I think this is what Cheery describes.
A benefit of that is easy extensibility. You just have to add some entries to the table. This table could be hard coded or even loaded at run-time.
Similar to Epaga's suggestion you coul also try to solve this via polymorphism, having specialized classes perform actions for the different cases. The drawback here is that you have to write new classes in case of changes.
You want to split this up into multiple functions, one for each ID, and one for each operation.
A guideline I normally use is a screen height. If I can't have a function in full fit on my screen I start thinking about splitting things up. That way you don't need to scroll just to see where the function is going. As I said, it's a guideline, not a rule, but I find it more practical to be in control of the structure.
If you then want to take an OO approach and turn this into a bunch of classes, you're welcome to do so if you see an advantage. Be mindful of all the plumbing that goes with it, though. You might want to keep it simple.
Dave
I've seen a solution to this problem that worked well: a hash table of functions.
At compile time a Perfect Hash Function is created for each supported operation and the operation is associated with a function to call (the function pointer is the value in the hash, the command string is the key).
During runtime, the command functionality is called by using the command string to find the function in the hash table. Then the function is called passing the "data" string by reference. Each command function then parses out the remaining string according to its rules... the strategy pattern also applies at this point.
Makes the code work like a state machine, which is (IMHO) the easiest way to approach networking code.
Create a map of functions. Then you'd have code like:
consumed_count = token_mapper[tokens[0]](tokens)
remove amount of consumed tokens according to the return value and repeat.
Though, I don't understand your approach anyway, You are going to write a language that's hard to handle and inflexible. Think about it: A small difference in the amount of arguments causes real havoc in that language. Therefore you are always limited to 1-3 arguments per command.
I'd rather just use some lexer/parser generator combination, but if you want to do what you are going to do, I'd propose you at least split first with newline, then with space, and have therefore clear way to see whether it was meant to give 2 or 3 arguments.
It's important even if your language would be machine-generated, what if your generator ends up having a bug? Fail early, fail often.
you could use the command pattern...... each of your actions would know its id and operation and add itself to to a list at run time...then you'd simply look up the right command, pass it whatever context it needs and it will execute the operation.
The table driven aproach seems to fit this, like mxp said. If you have diffrent number of parameters for your functions you could have a column in the table that specifies the number of parameters for the function on the same row.