What I mean is, I'm making a program that takes parameters from the user (as many as he wishes to enter at one time) by means of the console, e.g.
-p /users/me/myFolder/myHtmlFile.html -d /users/me/myOtherFolder -n myHmtlFileStyles -r
would set the parameters -p, -d and -n, then run the program (cause that's what -r does). I've already written a function that goes through each substring surrounded by whitespace in the input string. So I suspect the n00b design pattern would be something like
if (this_substring == "-p")
{
// ... run some procedure
}
else if (this_substring == "-d")
{
// ... run some procedure
}
else if (this_substring == "-n")
{
// ... run some procedure
}
else if (this_substring == "-r")
{
// ... run some procedure
}
else
{
// ... trigger not recognized; throw an error
}
but I'm sure there is a more elegant and proper way to do it. For instance, is there a way of mapping strings to functions? Does there exist something like
std::map<std::string, function> triggerMap = {{"-p", function1()}, {"-d", function2()}, "-n", function3()}, {"-r", function4()}};
??????
You can build an std::unordered_map from strings to function objects, initialize the function object with a lambda and call it based on its key:
std::unordered_map<std::string, std::function<void()>> fns {
{
"-p",
[]() {
// do stuff
}
},
{
"-d",
[]() {
// do something else
}
}
};
fns[param]();
It depends upon which standard you are following. I strongly suggest to use C++11 (e.g. with a recent GCC 4.9 compiler, using -std=c++11). Then use std::function and anonymous lambdas closures.
BTW, you could use (if on Linux) glibc parsing program arguments facilities.
Of course, you can use function pointers.
But I would recommend you to just use getopt
See: http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html
In your case:
while ((c = getopt (argc, argv, "p:d:n:r:")) != -1)
{
switch (c)
{
case 'p':
function(optarg);
break;
case 'd':
function(optarg);
break;
case 'n':
function(optarg);
break;
case 'r':
function(optarg);
break;
}
}
Use switch and a bunch of cases. Identify the flags (-r, -n, etc), extract the character and use that as the case label. Not as elegant, perhaps, as anonymous lambda closures, but more generically C++.
Related
In C and in javascript I enjoy the ability to write this kind of thing and have it just work.
while (a)
{
ctx: while(b)
{
while (c)
{
if(d) break ctx;
...
}
}
...
}
Perhaps I'm just confused about C++ versions but I get this kind of error in g++:
error: expected ‘;’ before ‘ctx’
break ctx;
error: ‘ctx’ was not declared in this scope
warning: label ‘ctx’ defined but not used [-Wunused-label]
ctx:
C++ appears to refuse letting me write this code.
C++ has added lambdas/closures that potentially would let me do this but I'm not quite sure how they would work in this case.
Using try throw catch is the closest construct I can think of that produces this behavior but the sloppiness of using an error system when none should be needed concerns me (Also they are slow I hear).
I'm tempted to just wrap it in extern C except I'm relying on c++ library's completely for the entire project so this also feels sloppy.
Is a try block or just rewriting my only options?
Neither C nor C++ have a labelled break statement (You're probably using a language extension, rather than standard C).
Instead, you can use goto to break out of a nested loop.
while (a)
{
while(b)
{
while (c)
{
if(d)
goto break_b;
}
}
break_b:
// ...
}
I was able to use goto to solve this... I though it was a banned construct in c++?
No. goto is not "banned" in C++.
This is a completely fine way to use goto. There doesn't exist an equivalent structured control statement.
lambdas/closures [...] potentially would let me do this but I'm not quite sure how they would work in this case.
If you are allergic to goto, then you can indeed use a lambda, but I don't see it providing any additional readability:
while (a)
{
[&](){
while(b)
{
while (c)
{
if(d)
return;
}
}
}();
// ...
}
Instead of a lambda, you can use a named function. But in that case you need to pass any variables (such as b, c and d) as arguments (assuming they're not globals).
Yet another way is an extra variable:
while (a)
{
bool break_b = false;
while(b)
{
while (c)
{
if(d) {
break_b = true;
break;
}
}
if (break_b)
break;
}
// ...
}
Of these three methods, I recommend goto, since it's the most readable. Except in the case the actual inner loop omitted from the example is very long, in which case a separate function might be better.
As has already been pointed out by others, goto would be a way to do exactly what you're asking for.
That being said, I would argue that, before asking the question of how to break out of a massively-complicated control flow structure, you should first ask yourself why there is a massively-complicated flow structure to begin with. What is going on in these loops? Should whatever is going on in each of these loops not better be moved into its own function? For example, instead of
while (a)
{
ctx: while (b)
{
while (c)
{
if (d) goto ctx;
…
}
}
…
}
why not
bool doC()
{
while (c)
{
if (d)
return false;
…
}
return true;
}
void doB()
{
while (b && doC());
}
and then
while (a)
{
doB();
…
}
Replacing the break with a goto here is not advisable. There can be issues wrt constructors and destructors not being called correctly. Whilst goto still exists in C++, it's really not something you want to use unless you really know what you're doing! A safer option would be to use a try-catch block. A better approach would be to re-factor your algorithm (currently it's O(N^3), which should really be ringing some alarm bells!)
while (a)
{
try
{
while(b)
{
while (c)
{
if(d) throw;
}
}
}
catch(...)
{
}
}
It is OK to use the standard 'true' and 'false' inside a switch statement, like so:
void handle_a_bool (bool value_to_be_handled)
{
switch (value_to_be_handled)
{
case true:
// Yay.
break;
case false:
// #$#%.
break;
};
};
I guess what I really want to know is whether the standard 'bool' type in C++ is a constant or something else.
Yes, it is legal, but why would you do that? Just use this:
if (value_to_be_handled)
{
// ...
}
else
{
// ...
}
The version based on switch just makes the code harder to read and doesn't bring any additional benefit.
You may use it, but as for me it's extremely hard to read.
Why to not use just
void handle_a_bool (bool value_to_be_handled) {
if(value_to_be_handled) {
}
else{
}
};
?
do{...} while(0);
the usage of do{}while(0); in my coding is used because, i do not want to use long if else nested conditional statements. I eventually give an break at the time of failure and move out of the loop, with a assurance that my function would have been traversed at least 1 time.
Now, the problem comes with the code warning tools, I am getting a warning at the usage of do{...}while(0);
the usage of nested if(){} else{} is less readable, high complex. and lets the code to be having dead code.
if i exclude nested if(){} else{} and do{} while(0); , do we left part with some other way to make code readable with understandable logic;
if(status_of_funcA_ok != funcA())
{ //failure}
else if (status_of_funcB_ok != funcB())
{//failure}
else if (status_of_funcC_ok != funcC())
else
{//Great}
do{
if(status_of_funcA_ok != funcA())
break;
if (status_of_funcB_ok != funcB())
break;
if (status_of_funcC_ok != funcC())
break;
}while(0);
Move the complete logic of the do while{0} loop to a function, and replace the break with return. And call the function, instead of the loop.
You will not have to worry about the beauty.
The compiler also doesn't have to complain about the do while{0}.
All the more, by adding a bit of modularity, the program might be a little more readable.
In any case, before doing this, it would be nice to check whether your compiler is in an extremely pedantic mode, and you might want to turn that off. That might take the warning away.
ss.
PS: You don't seem to need a return value for the function, but you could have that to get a clue of which function was successful.
I am using this pattern too, for those who wonder, here's an abstract example:
do // while(0) for break
{
state1 = 0;
if (cond1())
{
if (cond2())
break;
state1 = opA();
}
if (cond3() || state1 && state1->cond4())
break;
...
Triumph(state1, ...);
// often here: return
}
Failure(state1, ...);
I consider this valid in the following circumstances:
you have a long-ish sequence (say, >~half a dozen of conditions)
the conditions are complex, and you use / build up significant state, so you can't
isolate the elements into functions
you are in an exception-unfriendly environment, or your break-ing code path is
not actually an exception
What you can do about it:
Silence the warning. It is just a warning, after all; and I don't see a "typical mistake" (like typing 0 instead of your condition) that would be caught by this warning.
[edit] Now, that was silly. the typical mistake that you catch with the warning is e.g. while (a1!=a1) instead of while (a1!=a2).[/edit]
Break into functions, move state to a class
this would transform above code to:
struct Garbler
{
State1 state1;
bool Step1()
{
state1 = 0;
if (cond1())
{
if (cond2())
return false;
state1 = opA();
}
return true;
}
bool Step2()
{
return cond3() || state1 && state1->cond4();
}
..
void Run()
{
if (Step1() && Step2() && ... && Step23())
Triumph(state1, ...);
else
Failure(state1, ...);
}
}
This is arguably less readable, worse is that you pull apart the sequence, which might lead to a very questionable class (where members may be called only in a certain order).
Scopeguards
This may allow to transform the breaks into early returns, which are more acceptable:
state1 = 0;
ScopeGuard gFailure = MakeGuard(&Failure, ByRef(state1), ...);
if (cond1())
{
if (cond2())
return;
state1 = opA();
}
if (cond3() || state1 && state1->cond4())
return;
// everything went ok, we can dismiss the scopeguard
gFailure.Dismiss();
Triumph(state1, ...);
They can be more elegantly written in C++0x, preserve the flow, but the solution isn't that flexible either, e.g. when Failure() cannot be isolated easily into a single function.
Nested nested if-else statements can become quite unreadable, but I think using do {..} while(0); as a replacement would be much worse. It is very unconventional and anybody else reading it would not really associate it with if-else statements.
There are a few things you can do to make nested if-else statements more readable. A few suggestions are:
optimize your logic - sometimes you can do away with a lot of if clauses when you 'refactor' your logic ex. grouping identical items.
use switch() - switch is generally more readable compared to if-else statements. You can associate an enum to each case and you can switch this.
encapsulate complicated logic with functions
You can use goto instead of do {} while(0) and break. This is not readable and not good practice either though. I think for each specific case there is a better way to avoid deep if/else structures. For example, sometimes using function calls can help:
for example instead of:
if(status_of_funcA_ok != funcA())
{ //failure}
else if (status_of_funcB_ok != funcB())
{//failure}
else if (status_of_funcC_ok != funcC())
else
{//Great}
you can write:
if (check_funcs() == 0) {
great();
}
int check_funcs() {
if (status_of_funcA_ok != funcA())
return -1;
if (if(status_of_funcB_ok != funcB()))
return -2;
if (if(status_of_funcC_ok != funcC()))
return -3;
return 0; /* great */
}
Sometimes, you can use exit().
Also, in c++ you can use throw() and try/catch:
try {
/* */
throw (this error);
/* */
throw (that error);
} catch (this error) {
} catch (that error) {
}
If there are more conditions to check avoid using if{} else{},
best practice is to Replace if else conditions with switch case
While playing with NLP I've been encountered with little problem:
switch(var1)
{
case Variant1_1:
if( cond1 )
{
if( cond2 )
{
if( cond3 )
{
switch(var2)
{
case Variant2_1:
return someExpression;
// another five-six cases
default:
return;
}
}
else // cond3
{
switch(var2)
{
case Variant2_1:
return someExpression;
// another five-six cases
default:
return;
}
}
}
else // cond2
{
if( cond3 )
{
switch(var2)
{
case Variant2_1:
return someExpression;
// another five-six cases
default:
return;
}
}
else // cond3
{
switch(var2)
{
case Variant2_1:
return someExpression;
// another five-six cases
default:
return;
}
}
}
}
else // cond1
{
// same thing
}
break;
case Variant1_2:
// same gigantic tree
break;
case Variant1_3:
// here too
break;
default:
return;
}
What alternatives are for such "computational tree"? The only thing that comes to my mind - some tree container with function pointers as leaves and a great deal of little functions.
(tongue in cheek) Every time you encounter a switch statement in a C++ program, you know that you've missed an inheritance opportunity.
The two ways I know to refactor multiple parallel switches are (1) building a multi-dimension array of function pointers, and (2) using a variation of the visitor pattern.
A nice workaround is using a matrix.
This will work well if you know that all the conditions will be evaluated anyway.
Make a multi-dimensional array that will map the true-false values to the handling functions.
Arrayswitch[var1][cond1][cond2][cond3][var2]();
I start looking for a data-driven approach when code starts to look like this. It may be as simple as a table or perhaps a tree with function pointers as you've suggested.
If this is a hand-rolled parser of some sort, you might want to look into some references on parsing for ideas on how to use a grammar definition to do the parsing (either by interpretting the grammar on demand, or by using a code-generation tool that uses the grammar as input).
I often hand-roll recursive descent parsers. Typically, I create a class that holds the state, expose one public "Parse" function, and implement each rule as a private member function. These member functions are small and explicitly named, so the code becomes quite readable. It's also very easy to write tests for it.
Polymorphism and good code design.
http://www.cs.bu.edu/teaching/cpp/polymorphism/intro/
What you're describing is what the compiler will make out of your code anyway :) So you're essentially proposing a nested programming language, which brings about Greenspun's law: "Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp."
There are ways of writing this code better to express your conditions. when you have a lot of nested if() { if () { if() } } }s, usually just writing if (!condition) break; or other escaping method, simplifies the code. not always but a lot of times.
What I want is to add possibility to interact with application, and be able to extract information from application or event ask it to change some states.
For that purpose I though of building cli utility. The utility will connect to the application and send user commands (one line strings) to the application and wait for response from the application.
The command should contain:
- command name (e.g. display-session-table/set-log-level etc.)
- optionally command may have several arguments (e.g. log-level=10)
The question to choose syntax and to learn parse it fast and correctly.
I don't want to reinvent the wheel, so maybe there's already an answer out there.
Take a look at the interpreter example (example usage) from Boost.FunctionTypes. Note however that as it is it only supports free functions.
boost::program_options is worth a look.
The Readline library could be useful.
I would suggest using a JSON library.
I use an unholy mix of readline, boost::spirit, and the factory pattern to handle all that. It wouldn't be nearly as unholy if it weren't for readlines unapologetic C syntax :)
The outer loop looks like this
while(true)
{
char *line(NULL);
line = readline((cmd.leaf() + " > ").c_str());
if (line && *line)
{
add_history(line);
int error = ParseLine(line,*s_g, std::cout);
free(line);
if (error == ErrQuit)
break;
if (error == ErrSave)
....
Each command has a completion function and a parser/completion function
char **completeCreate(const std::vector<std::string> &, const char *text, int depth)
{
switch (depth)
{
case 1:
case 2:
{
return rl_completion_matches(text, rl_filename_completion_function);
break;
}
case 3:
{
return rl_completion_matches(text, rulesFill);
break;
}
}
return NULL;
}
Defines the completer for a command that takes two arguments, a filename and a string, which gets registered with the completion mechanism of readline through a factory + macro, that lets me register everything with something that looks like this
REG_COMP(Create, completeCreate);
On the parser side, I have a similar factory setup
int parseCreate(const std::vector<std::string> &names, Game &g, std::ostream &out)
{
if (names.size() != 4)
return parseHelpC(names, g, out);
if (!CreateGame(names[1],names[2],names[3],g))
return ErrGameCreation;
return ErrNone;
}
REG_PARSE(Create,"CardList PowerList RuleSet");
that provides the actual logic and help text
I've left out huge swaths of code that glues everything together, but would be happy to share the hideousness that is the code base (it is currently a private git repository) I look forward to see if someone has something that works better.