c++ - conditional assignment of const, without ternary? - c++

suppose I want to assign a const variable based on complex calculations which depend on a conditional.
if the situation were simple, I could do:
const int N = myBool ? 1 : 2;
but it's more like
const int N = myBool ? <lengthy calculation> : <other lengthy calculation>;
What I'm doing is this, but I'd like something cleaner:
int N_nonconst;
if (myBool) {
N_nonconst = <lengthy calculation>;
}
else {
N_nonconst = <other lengthy calculation>;
}
const int N = N_nonconst;
obviously, I could also do this:
int possibility1 = <lengthy calculation>;
int possibility2 = <other lengthy calculation>;
const in N = myBool ? possibility1 : possibility2;
but I'd like to actually perform only one of those lengthy calculations.
If I were extending the language, I'd consider making something like a const_deferredAssignment declaration:
const_deferredAssignment int N;
if (myBool) {
N = <...>;
}
else {
N = <...>;
}
I could also wrap those calculations up in functions/methods, but they use a bunch of locals, so it would be a fairly verbose function call.

You could wrap each calculation in a lambda, and capture the local variables to reduce the verbosity of their arguments
{
// ...
auto firstFunc = [&]() -> int { ... };
auto secondFunc = [&]() -> int { ... };
const int N = myBool ? firstFunc() : secondFunc();
}
In this way only one of the two functions are actually executed.

You could move the lengthy calculations to a separate function:
int lengthCalculation()
{
if(myBool)
{
return <lengthy calculation>;
}
else
{
return <other lengthy calculation>;
}
}
const int N = lengthCalculation();
If you don't want to create a separate function that you can use a local lambda:
const int N = [&]()
{
if(myBool)
{
return <lengthy calculation>;
}
else
{
return <other lengthy calculation>;
}
}();

you could try and use
SWITCH(myBool)
{
Case 0 : first_lengthy_calculation
Break;
Case 1 : second_lengthy_calculation
Break;
}

Related

C++ initialize reference and assign variable together

I have this section in my code where I am using an if else, and the ternary operator on the same bool condition. Is there a more elegant way to do this?
bool UseGroups //input parameter to a function.
std::vector<std::vector<int>>& relevantGamesGroup = (useGroups) ? (objFlight.gamesGroup[dayIndex]) : (objFlight.gamesSubGroups[dayIndex]);
if (useGroups) {
numberOfGroups = objFlight.numberOfGroups[dayIndex];
}
else {
numberOfGroups = 2 * (objFlight.numberOfGroups[dayIndex]);
}
I would probably write it like this, because I find it quite clear to read:
auto& relevantGamesGroup = useGroups
? objFlight.gamesGroup[dayIndex]
: objFlight.gamesSubGroups[dayIndex];
auto numberOfGroups = useGroups
? objFlight.numberOfGroups[dayIndex]
: objFlight.numberOfGroups[dayIndex] * 2;
If you need to use the variables relevantGamesGroup and numberOfGroups after only having checked the condition once, you could create and call a temporary lambda that you make return the necessary pair:
auto&& [relevantGamesGroup, numberOfGroups] =
[&]() -> std::pair<std::vector<std::vector<int>>&, int>
{
if (useGroups) return {objFlight.gamesGroup[dayIndex],
objFlight.numberOfGroups[dayIndex]};
return {objFlight.gamesSubGroups[dayIndex],
2 * objFlight.numberOfGroups[dayIndex]};
}();
// use relevantGamesGroup and numberOfGroups here
An alternative using the ternary/conditional operator instead of using a lambda:
auto&& [relevantGamesGroup, numberOfGroups] =
useGroups ? std::pair<std::vector<std::vector<int>>&, int>
{objFlight.gamesGroup[dayIndex],
objFlight.numberOfGroups[dayIndex]}
: std::pair<std::vector<std::vector<int>>&, int>
{objFlight.gamesSubGroups[dayIndex],
2 * objFlight.numberOfGroups[dayIndex]};
// use relevantGamesGroup and numberOfGroups here
If you use this kind of construct a lot, creating a helper function could simplify it:
#include <tuple>
template<class... Ts>
std::tuple<Ts...> ternary(bool cond, std::tuple<Ts...>&& True,
std::tuple<Ts...>&& False) {
return cond ? True : False;
}
You'd then supply the wanted types as template parameters and use structured bindings to extract the selected values / references just like above:
int main() {
int a1 = 1, b1 = 2, c1 = 3;
int a2 = 40, b2 = 50, c2 = 60;
auto&&[a,b,c] = ternary<int&,int&,int&>(true, {a1,b1,c1}, {a2,b2,c2});
std::cout << a << b << c << '\n';
++a; ++b; ++c; // these are references to a1, b1 and c1
std::cout << a1 << b1 << c1 << '\n';
}
Output:
123
234
With the types in your question, it could look like this:
void func(bool useGroups) {
auto&& [relevantGamesGroup, numberOfGroups] =
ternary<std::vector<std::vector<int>>&, int>(useGroups,
{objFlight.gamesGroup[dayIndex], objFlight.numberOfGroups[dayIndex]},
{objFlight.gamesSubGroups[dayIndex], 2 * objFlight.numberOfGroups[dayIndex]});
// use relevantGamesGroup and numberOfGroups here
}
Not sure whether it is more "elegant", but if you insist of writing only one if/else, then either use a pointer instead of reference for relevantGamesGroup which can be default-initialized and assigned later, or a lambda can help:
auto& relevantGamesGroup = [&]()->decltype(auto){
if (useGroups) {
numberOfGroups = objFlight.numberOfGroups[dayIndex];
return objFlight.gamesGroup[dayIndex];
} else {
numberOfGroups = 2 * (objFlight.numberOfGroups[dayIndex]);
return objFlight.gamesSubGroups[dayIndex];
}
}();
(Note that ->decltype(auto) is important here, since the lambda will otherwise return by-value, not by-reference.)
And for completeness the clearly worse way of doing it with just one ternary operator:
auto& relevantGamesGroup = useGroups
? ((void)(numberOfGroups = objFlight.numberOfGroups[dayIndex]),
objFlight.gamesGroup[dayIndex])
: ((void)(numberOfGroups = 2 * (objFlight.numberOfGroups[dayIndex])),
objFlight.gamesSubGroups[dayIndex]);
((void) cast optional if you are not using some very weird type for numberOfGroups)
This code looks fine to me. Here's how I would rewrite it, but it's mostly a matter of style.
bool useGroups;
// Use of auto
auto& relevantGamesGroup = useGroups ? objFlight.gamesGroup[dayIndex] : objFlight.gamesSubGroups[dayIndex];
numberOfGroups = objFlight.numberOfGroups[dayIndex];
if (useGroups) {
numberOfGroups *= 2;
}
This is clean and can be fixed by Joe the Intern if needed be.
using GroupGames = std::vector<std::vector<int>>;
GroupGames* relevantGamesGroup;
if (useGroups) {
relevantGamesGroup = &objFlight.gamesGroup[dayIndex];
}
else {
relevantGamesGroup = &objFlight.gamesSubGroups[dayIndex];
}
if (useGroups) {
numberOfGroups = objFlight->numberOfGroups[dayIndex];
}
else {
numberOfGroups = 2 * (objFlight->numberOfGroups[dayIndex]);
}
Or with the suggestion of #Ted Lyngmo below, it's even cleaner.
using GroupGames = std::vector<std::vector<int>>;
GroupGames* relevantGamesGroup = &objFlight.gamesSubGroups[dayIndex];
int numberOfGroups = 2 * (objFlight->numberOfGroups[dayIndex]);
if (useGroups) {
relevantGamesGroup = &objFlight.gamesGroup[dayIndex];
numberOfGroups = objFlight->numberOfGroups[dayIndex];
}

Return from calling function inside lambda

Lambdas are an awesome way to create reusable code inside a function/method without polluting the parent class. They're a very functional replacement for C-style macros most of the time.
However, there's one bit of syntactic sugar from macros that I can't seem to replicate with a lambda, and that's the ability to exit from the containing function. For example, if I need to return while checking the range of a series of ints, I can do that easily with a macro:
const int xmin(1), xmax(5);
#define CHECK_RANGE(x) { if((x) < xmin || (x) > xmax) return false; }
bool myFunc(int myint) {
CHECK_RANGE(myint);
int anotherint = myint + 2;
CHECK_RANGE(anotherint);
return true;
}
Obviously this is an oversimplified example, but the basic premise is that I'm performing the same check over and over on different variables, and I think it's more readable to encapsulate the check and related exits. Still, I know that macros aren't very safe, especially when they get really complex. However, as far as I can tell, trying to do the equivalent lambda requires awkward additional checks like so:
const int xmin(1), xmax(5);
auto check_range = [&](int x) -> bool { return !(x < xmin || x > xmax); };
bool myFunc(int myint) {
if(!check_range(myint)) return false;
int anotherint = myint + 2;
if(!check_range(anotherint)) return false;
return true;
}
Is there a way to do this with a lambda? Or am I missing some alternative solution?
Edit: I recognize that returning from inside a macro is generally a bad idea unless significant precautions are taken. I'm just wondering if it's possible.
You are correct--there's no way to return from the caller from inside a lambda. Since a lambda can be captured and stored to be called later, from inside an arbitrary caller, doing so would result in unpredictable behavior.
class Foo
{
Foo(std::function<void(int)> const& callMeLater) : func(callMeLater) {}
void CallIt(int* arr, int count)
{
for (index = count; index--;)
func(count);
// do other stuff here.
}
std::function<void(int)> func;
};
int main()
{
auto find3 = [](int arr)
{
if (arr == 3)
return_from_caller; // making up syntax here.
};
Foo foo(find3);
};
Is there a way to do this with a lambda?
Not exactly like the macro but your lambda, instead of returning a bool, can throw a special exception (of type bool, by example)
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
and the function myFunc() can intercept this special type
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
For a single check_range() call, this is (I suppose) a bad idea; if you have a lot of calls, I suppose can be interesting.
The following is a full working example
#include <iostream>
constexpr int xmin{1}, xmax{5};
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
int main ()
{
std::cout << myFunc(0) << std::endl; // print 0
std::cout << myFunc(3) << std::endl; // print 1
std::cout << myFunc(7) << std::endl; // print 0
}
No better way to do this than just to use the return value of the lambda and then return from the calling function. Macros are ew for this.
As it stands in C++, that is the idiomatic way to exit from a function that uses another condition to determine whether or not to exit.
Not C++11, but people have hacked C++2a coroutines to basically do this.
It would look a bit like:
co_await check_range(foo);
where the co_await keyword indicates that in some cases, this coroutine could return early with an incomplete result. In your cases, this incomplete result would be non-resumabable error.
The playing around I saw was with optionals, and required using a shared ptr, but things may improve before it is standardized.

Checking function pointers type

Let define a structure parser :
struct parser {
int (*buffer_push_strategy)();
int (*escape_buffer_push_strategy)();
int (*do_callback_strategy)();
};
I have an initialization function :
int parser_init() {
if (some_condition) {
parser->buffer_push_strategy = buffer_push_strategy1;
parser->escape_buffer_push_strategy = escape_buffer_push_strategy1;
parser->do_callback_strategy = do_callback_strategy1;
}
else {
parser->buffer_push_strategy = buffer_push_strategy2;
parser->escape_buffer_push_strategy = escape_buffer_push_strategy2;
parser->do_callback_strategy = do_callback_strategy2;
}
return 0;
}
where the strategy functions are defined somewhere.
Ok, so my interest is to determine which strategy has been used when I write the unit tests. Any idea how to accomplish that?
I saw something on internet about is_pointer function from C++ 11, but I don`t think this would help me.
parser is a variable:
struct parserT {
int (*buffer_push_strategy)();
int (*escape_buffer_push_strategy)();
int (*do_callback_strategy)();
} parser;
If you want to know which the strategy is, you could use:
int strategy= (parser->buffer_push_strategy == buffer_push_strategy1) ? 1 : 2;
Perhaps, you prefer to store the strategy number:
int parser_init() {
if (some_condition) {
parser->buffer_push_strategy = buffer_push_strategy1;
parser->escape_buffer_push_strategy = escape_buffer_push_strategy1;
parser->do_callback_strategy = do_callback_strategy1;
return 1;
}
else {
parser->buffer_push_strategy = buffer_push_strategy2;
parser->escape_buffer_push_strategy = escape_buffer_push_strategy2;
parser->do_callback_strategy = do_callback_strategy2;
return 2;
}
}
Then, you could init the parser as:
const int STRATEGY= parser_init();
You can compare function pointers
if(p.buffer_push_strategy == buffer_push_strategy1)
See https://ideone.com/QQzL1c

Is there any functional difference between the following 2 code snippets?

Is there any functional difference between the following 2 code snippets?
bool ColorClass::setTo(int inRed, int inGreen, int inBlue)
{
amountRed = inRed;
amountGreen = inGreen;
amountBlue = inBlue;
return clipColor(amountRed, amountGreen, amountBlue);
}
bool ColorClass::setTo(int inRed, int inGreen, int inBlue)
{
amountRed = inRed;
amountGreen = inGreen;
amountBlue = inBlue;
if (clipColor(amountRed, amountGreen, amountBlue))
{
return true;
}
else
{
return false;
}
}
The functions the above code calls are defined below:
bool ColorClass::clipColor(int &checkRed, int &checkGreen, int &checkBlue)
{
int numClips = 0; //numClips is used to counter number of clips made
checkColorBounds(checkRed, numClips);
checkColorBounds(checkGreen, numClips );
checkColorBounds(checkBlue, numClips);
return (numClips != 0);
}
void ColorClass::checkColorBounds(int &color, int &clipCounter)
{
if(color > MAXCOLOR)
{
color = MAXCOLOR;
clipCounter++;
}
else if (color < MINCOLOR)
{
color = MINCOLOR;
clipCounter ++;
}
}
I tested both and gone through both, and I can't seem to notice anything functionally different.
I like the first one better, because it is much more succint and more efficient (avoids the if-else)
There're no any functional differences at all. Then use the 1st one.
KISS

What is a "yield return" equivalent in the D programming language?

Here is a simple generator in C#.
IEnumerable<int> Foo()
{
int a = 1, b = 1;
while(true)
{
yield return b;
int temp = a + b;
a = b;
b = temp;
}
}
How do I write a similar generator in Digital Mars D?
(The question is about the yield return statement)
Thanks!
Update.
That's interesting. Since I'm just generating a mathematical sequence, using recurrence may be a good option.
auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1);
foreach (e; take(fib, 10)) // <- prints first ten numbers from the sequence
{
writeln(e);
}
There's no exact equivalent in D. Here are some rough equivalents:
Using opApply-style internal iteration. This doesn't allow iterating over two iterators in lockstep, though:
struct Foo {
int opApply(int delegate(ref int) dg) {
int a = 1, b = 1;
int result;
while(true) {
result = dg(b);
if(result) break;
int temp = a + b;
a = b;
b = temp;
}
return result;
}
}
void main() {
// Show usage:
Foo foo;
foreach(elem; foo) {
// Do stuff.
}
}
Use ranges. These are slightly harder to write in some cases, but are very efficient and allow lockstep iteration. This can also be iterated over with a foreach loop, exactly like the opApply version:
struct Foo {
int a = 1, b = 1;
int front() #property {
return b;
}
void popFront() {
int temp = a + b;
a = b;
b = temp;
}
// This range is infinite, i.e. never empty.
enum bool empty = false;
typeof(this) save() #property { return this; }
}
If you really need coroutine-style stuff you can combine ranges and opApply together using core.thread.Fiber, but you'll probably find that either ranges or opApply does what you need almost all the time.
See here; example excerpt below:
module main;
import std.stdio;
import generators;
void genSquares(out int result, int from, int to)
{
foreach (x; from .. to + 1)
yield!result(x * x);
}
void main(string[] argv)
{
foreach (sqr; generator(&genSquares, 10, 20))
writeln(sqr);
}
The std.concurrency module now has a Generator class which makes this even easier (and you don't need a third-party library).
The class is an input range, so it can be used with for loops and all the standard std.range/std.algorithm functions.
import std.stdio;
import std.range;
import std.algorithm;
import std.concurrency : Generator, yield;
void main(string[] args) {
auto gen = new Generator!int({
foreach(i; 1..10)
yield(i);
});
gen
.map!(x => x*2)
.each!writeln
;
}