enum { WITH_ZERO };
auto copy_num = [](int n, char target[NUM_LEN]) -> int {
char temp;
for (int j = NUM_LEN - 1; j >= 0; j--) {
if ((temp = n % 10 + '0') == '0') {
return WITH_ZERO;
} else {
target[j] = temp;
n /= 10;
}
}
return !WITH_ZERO;
};
if (copy_num(i, num_copy) == WITH_ZERO) {
continue;
}
if (i * 3 > MAX_NUM) {
continue;
}
copy_num(i * 2, num_double);
copy_num(i * 3, num_triple);
//edit: changed 'goto' to 'continue'
The above is part of my code, which should show in what cases I would prefer to use nested lambdas. I can achieve similar to this with macros, but they do make my codes dirtier, while the lambdas used this way look more clean, without the '\'s. The 'copy_num' function here is only used locally and not anywhere else, so this has more readability than when defining 'copy_num' as a normal function outside. Lambdas can also conveniently catch outer variables if needed, in which case I can reduce repetitive function parameters, again making clearer code.
By using lambdas this way several times, I wondered whether it is a good or bad idea to use lambdas as an entire replacement to functions. Lambdas can work perfectly well as a more flexible form of functions possible to be nested or anonymous. In cases where what the lambdas do are of no difference than what a normal function of a same form would do, the compiler will be smart enough to compile them as if being plain functions.
Or perhaps future c/c++ will allow nested functions in general?
I do not think there is anything wrong with this approach. It is certainly safer than C'ish #define's, the savings in \s being the least advantage I can think of.
Until lambda support has matured, you may see compilers struggle to generate 'optimal' code though.
Lambdas can also conveniently catch outer variables if needed, in which case I can reduce repetitive function parameters, again making clearer code.
Yes, and once needed elsewhere, the lambda + capture can easily be migrated to a class that holds state and defines some operations on it.
Or perhaps future c/c++ will allow nested functions in general?
This is fully-fleshed support for nested functions. Remember, a lambda that does not capture can decay to a function pointer.
Related
A lot of internet resources insist on checking preconditions in API functions via if (something_is_wrong) throw Exception{} instead of assert(!something_is_wrong) and I see some good points in it. However, I'm afraid such usage may result in doubling the same checks:
void foo(int positive) {
if (positive < 1) {
throw std::invalid_argument("param1 must be positive");
}
}
void caller() {
int number = get_number_somehow();
if (number >= 1) {
foo(number);
}
}
will probably execute like
int number = get_number_somehow();
if (number >= 1) {
if (number < 1) {
throw std::invalid_argument("param must be positive");
}
}
unless the call will actually be inlined and optimized by cutting out one of the ifs, I guess. Besides, writing the check twice (in foo() and in caller()) might be violating the DRY rule. Therefore, maybe I should go for
void caller() {
int number = get_number_somehow();
try {
foo(number);
} catch (std::invalid_argument const&) {
// handle or whatever
}
}
to evade repeating myself with those precondition checks, providing a bit of performance and a lot of maintainability in case of a function contract change.
However, I can't always apply such logic. Imagine std::vector having only at() but not operator[]:
for (int i = 0; i < vector.size(); ++i) {
bar(vector.at(i)); // each index is checked twice: by the loop and by at()
}
This code results in extra O(N) checks! Isn't it too much? Even if it is optimized out the same way as above, what about such situations with indirect calls or long functions, which probably won't be inlined?
So, should my program be written according to the rules below?
if an API function probably won't be inlined or is expected to be called a lot of times with checks on the call site (see the vector example), assert() its preconditions (inside it);
try-catch throwing functions instead of checking their preconditions before the call (the latter seems to break DRY).
If not, why?
So, there are two separate things you are talking about: DRY and performance.
DRY is about code maintenance and structure, and doesn't really apply to code you can't control. So, if the API is a black-box, and there happens to be code inside of it that you can't change, but you need to have separately, then I wouldn't think of it as not DRY to repeat it in your code. Y is Yourself.
But, you could still care about performance. If you measure a performance problem then fix it with whatever makes sense -- even if it's anti-DRY (or it's ok if it is).
But, if you control both sides (the API and the client) and you really want a pure, no-repeat, performant solution, then there's a pattern something like this pseudocode. I don't know the name, but I think of it as "Proof Providing"
let fn = precondition_check(myNum)
if fn != nil {
// the existence of fn is proof that myNum meets preconditions
fn()
}
The API func precondition_check returns a function that captures the myNum in it and doesn't need to check if it meets preconditions because it was only created if it did.
This question already has answers here:
Modern C++ way to repeat code for set number of times
(3 answers)
Closed 2 years ago.
I want to execute a single operation multiple times, without defining a counter. For example, like this:
do(10)
{
//do something
}
I think this would be useful in several different scenarios. For example:
Deleting several consecutive items from std::list by a beginning index.
Emitting some signal several times, either over time or at some specific time.
Adding the same data to the list for custom initialization
Many scenes are not limited to those listed above.
Other languages have syntax similar to this that allows repeatedly executing the same command, without having to explicitly define a counter variable.In my opinion,defining a counter is completely inconsistent with human thinking.
Simulate how we think:
In reality, we always do sth. a few times directly.
But now the syntax looks like this:
Uh...I am going to do sth. three times.
Okay,ready,I started.
Soul torture: Why doesn't C++ provide a concise syntax? Although I am a fan of C++, I can’t help but wonder why some people don’t like C++ because C++ rarely considers how people think.I hope C++ can advance with the times and become the programming language of the future.
Different from Modern C++ way to repeat code for set number of times.I gave my plan, application scenarios, and even emotional appeals.
The evolution of C++ is by committee. In the simplest terms folk propose stuff and the committee accepts or rejects it.
Interestingly your suggestion
do (integral_expression)
{
}
would not be a breaking change. Note there's no while after the loop body or while adjacent to do. integral_expression is almost a production rule in C++ in case labels of switch blocks, although it could be run-time evaluable in this case. It could even lend itself to clean code in the sense that the equivalent
for (int i = 0; i < integral_expression; ++i)
{
}
introduces i into the loop body which can be inconvenient as it can shadow an existing i.
That said, thought is needed for the case where integral_expression is negative. Perhaps introduce unsigned_integral_expression not unlike what needs to be written as the size expression when declaring a variable length array in a reasonably common extension to standard C++?
If you want this feature in C++, then why not propose it?
Here is an example of C++ code that will do something a given number of times. Could also be done in C, but the functor would have to be a function pointer.
There may be a use case for this, but I'd think that for C++ programs the standard loop syntax would be preferable.
#include <iostream>
#include <functional>
static void Do(int count, std::function<void(int)> fn)
{
while(count)
{
if (count > 0) --count;
else if (count < 0) ++count;
fn(count);
}
}
int main()
{
Do(10, [](int count) { std::cout << "Loop is at " << count << "\n"; });
}
lambdas make a clean pure library implementation possible if needed:
template<typename F>
constexpr void repeat(std::size_t const n,F const& f){
for (std::size_t i=0;i<n;++i)
f();
};
int x{};
repeat(5,[&]{
std::cout << ++x << std::endl;
});
such a proposal is likely to get discarded by the committee, unless greater reasons support it.
I have a function which internally uses some helper functions to keep its body organized and clean. They're very simple (but not always short) (they're more than just 2), and could be easily inlined inside the function's body, but I don't want to do so myself because, as I said, I want to keep that function's body organized.
All those functions need to be passed some arguments by reference and modify them, and I can write them in two ways (just a silly example):
With normal functions:
void helperf1(int &count, int &count2) {
count += 1;
count2 += 2;
}
int helperf2 (int &count, int &count2) {
return (count++) * (count2--);
}
//actual, important function
void myfunc(...) {
int count = count2 = 0;
while (...) {
helperf1(count, count2);
printf("%d\n", helperf2(count, count2));
}
}
Or with lambda functions that capture those arguments I explicitly pass in the example above:
void myfunc(...) {
int count = count2 = 0;
auto helperf1 = [&count, &count2] () -> void {
count += 1;
count2 += 2;
};
auto helperf2 = [&count, &count2] () -> int {
return (count++) * (count2--);
};
while (...) {
helperf1();
printf("%d\n", helperf2());
}
}
However, I am not sure on what method I should use. With the first, one, there is the "overhead" of passing the arguments (I think), while with the second those arguments could be (are them?) already included in there so that that "overhead" is removed. But they're still lambda functions which should (I think, again) not be as fast as normal functions.
So what should I do? Use the first method? Use the second one? Or sacrifice readability and just inline them in the main function's body?
Your first and foremost concern should be readability (and maintainability)!
Which of regular or lambda functions is more readable strongly depends on the given problem (and a bit on the taste of the reader/maintainer).
Don't be concerned about performance until you find that performance actually is an issue! If performance is an issue, start by benchmarking, not by guessing which implementation you think is faster (in many situations compilers are pretty good at optimizing).
Performance wise, there is no real issue here. Nothing to decide, choose whatever.
But, Lambda expressions won't do you any good for the purpose you want them.
They won't make the code any cleaner.
As a matter of fact I believe they will make the code a bit harder to read compared to a nice calculator object having these helper functions as member functions properly named with clean semantics and interface.
Using Lambda is more readable but they are actually there for more serious reasons , Lambda expressions are also known as "anonymous functions", and are very useful in certain programming paradigms, particularly functional programming, which lambda calculus ( http://en.wikipedia.org/wiki/Lambda_calculus )
Here you can find the goals of using lambdas :
https://dzone.com/articles/why-we-need-lambda-expressions
If you won't need the two helper functions somewhere else in your code, then use your lambda method , but if you will call one of them again somewhere in your project avoid writing them each time as lambdas , you can make a header file called "helpers.(h/hpp)" & a source file called "helper.(c/cpp)" then append all the helper functions there then you gain the readability of both the helper file and the caller file
You can avoid this unskilled habit and challange yourself by writing complex code that you have you read it more than once each time you want to edit it , that increases your programming skills and if you are working in a team , it won't be a problem , use comments , that will let them show more respect to your programming skills (if your complex code is doing the expected behaviour and giving the expected output)
And don't be concerned about performance until you find yourself writing a performance critical algorithm , if not , the difference will be in few milliseconds and the user won't notice it , so you will be loosing you time in an optimization that compiler can do by itself most of the time if you ask him to optimize your code .
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Why there is a need of 3 different loops : "while", "do-while", and "for" to exist in c/c++, especially when each of them gives you power to do almost anything that the other 2 can do? Other languages lack one or the other.
Is it just for ease of use or to make the code look better in cases, or are there any special purposes that are served by any one of them specifically that can't be accomplished so easily with the other two? If yes, then please mention.
P.S. - In general, do a language support many iteration syntax just to enhance readability?
It's not just readability, it's also the closely-related but distinct maintainability, and concision, and scoping (esp. for files, locks, smart pointers etc.), and performance....
If we consider the for loop, it:
allows some variables to be defined - in the for loop's own scope - and initialised,
tests a control expression before entering the loop each time (including the first), and
has a statement that gets executed after each iteration and before re-testing the control expression, assuming no break/return/throw/exit/failed assert etc., and regardless of whether the last statement in the body executed or whether a continue statement executed; this statement is traditionally reserved for logically "advancing" some state "through" the processing, such that the next test of the control expression is meaningful.
That's very flexible and given the utility of more localised scopes to ensure earlier destructor invocation, can help ensure locks, files, memory etc. are released as early as possible - implicitly when leaving the loop.
If we consider a while loop...
while (expression to test)
...
...it's functionally exactly equivalent to...
for ( ; expression to test; )
...
...but, it also implies to the programmer that there are no control variables that should be local to the loop, and that either the control "expression to test" inherently "progresses" through a finite number of iterations, loops forever if the test expression is hardcoded true, or more complicated management of "progress" had to bed itself controlled and coordinated by the statements the while controls.
In other words, a programmer seeing while is automatically aware that they need to study the control expression more carefully, then possibly look more widely at both the surrounding scope/function and the contained statements, to understand the loop behaviour.
So, do-while? Well, writing code like this is painful and less efficient:
bool first_time = true;
while (first_time || ...)
{
first_time = false;
...
}
// oops... first_time still hanging around...
...compared to...
do
...
while (...);
Examples
While loop:
int i = 23;
while (i < 99)
{
if (f(i)) { ++i; continue; }
if (g(i)) break;
++i;
}
// oops... i is hanging around
For loop:
for (int i = 23; i < 99; ++i)
{
if (f(i)) continue;
if (g(i)) break;
}
Well, C++ has goto and you can use it to implement all three loops, but it doesn't mean that they should be removed. Actually it just increases readability. Of course you could implement any of them yourself.
Some loops are easiest to write using for, some are easiest to write using while, and some are easiest to write using do-while. So the language provides all three.
We have things things like the += operator for the same reason; += doesn't do anything that you can't do with plain +, but using it (where appropriate) can make your code a bit more readable.
In general, when presented with different language constructs that accomplish similar purposes, you should choose the one that more clearly communicates the intended purpose of the code you are writing. It is a benefit that C provides four distinct structured iteration devices to use, as it provides a high chance you can clearly communicate the intended purpose.
for ( initialization ; condition ; iteration-step ) body
This form communicates how the loop will start, how it will adjust things for the next iteration, and what is the condition to stay within the loop. This construct lends itself naturally for doing something N times.
for (int i = 0; i < N; ++i) {
/* ... */
}
while ( condition ) body
This form communicates simply that you wish to continue to perform the loop while the condition remains true. For loops where the iteration-step is implicit to the way the loop works, it can be a more natural way to communicate the intention of the code:
while (std::cin >> word) {
/* ... */
}
do body while ( condition )
This form communicates that the loop body will execute at least once, and then continues while the condition remains true. This is useful for situations where you have already determined that you need to execute the body, so you avoid a redundant looking test.
if (count > 0) {
do {
/* ... */
} while (--count > 0);
} else {
puts("nothing to do");
}
The fourth iteration device is ... recursion!
Recursion is another form of iteration that expresses that the same function can be used to work on a smaller part of the original problem. It is a natural way to express a divide and conquer strategy to a problem (like binary searching, or sorting), or to work on data structures that self-referential (such as lists or trees).
struct node {
struct node *next;
char name[32];
char info[256];
};
struct node * find (struct node *list, char *name)
{
if (list == NULL || strcmp(name, list->name) == 0) {
return list;
}
return find(list->next, name);
}
For example
int f(int a) {
...
return a > 10;
}
is that considered acceptable (not legal, I mean is it ``good code''), or should it always be in a conditional, like this
int f(int a) {
...
if (a > 10)
return 1;
else
return 0;
}
It would be acceptable - if your return type was bool.
This is absolutely acceptable! In fact, Joel mentioned this on the latest stackoverflow podcast. He said it was the one thing he's had to show almost every programmer that starts at Fog Creek.
return a > 10 ? 1 : 0;
... makes more sense because you're returning an int, not a bool.
The first case is perfectly good, far better than the second, IMHO. As a matter of readability, I personally would do
return (a > 10);
but that is a minor nit, and not one everyone would agree on.
I don't see anything wrong with it. If anything it's more concise and I think most developers with moderate experience would prefer it.
The first is much preferable to me, since it is more concise. (And it avoids multiple returns:)
I'd rather write bool f(int); and the first form as bool is the boolean type in C++. If I really need to return an int, I'd write something like
int f(int) {
...
const int res = (i>42) ? 1 : 0;
return res;
}
I'd never understood why people write
if (expr == true)
mybool = true ;
else
mybool = false;
instead of the plain
mybool = expr;
Boolean algebra is a tool that any developer should be able to handle instinctively
Moreover, I'd rather define a named temporary as some debuggers don't handle function return values very well.
I think its perfectly acceptable, provided that you ensure that you make an extra effort to maintain readability. Like I would make sure that the method name is very unambiguous and you use good variable names.
The second alternative that you provided I think is almost worse because it involves a branch statement and multiple return statements and these things increase the complexity of the method while themselves reducing its readability.
Not only is that syntax 100% acceptable, you should also feel free to use boolean expressions outside of if statements, i.e. int x = i && ( j || k ); (or returning values like that).
I think part of it has to do with the style and culture of the language. The first example you have written is what would be expected from an experienced C programmer. They would much rather strangle themselves than put in an unnecessary block of statements.
I think it is perfectly acceptable when the language allows it and the usage is part of the paradigm of that language
I just tried three different variants with GCC:
int one(int x) { return (x > 42) ? 1 : 0; }
int two(int x) { return x > 42; }
int thr(int x) { if (x > 42) return 1; else return 0; }
As soon as you enable some optimization, the generated code for all of them is the same. So you should use the variant that is easiest to read.
I'll typically do the former over the latter.