Better way to pass bool variable as parameter? - c++

I am wondering if there is a better way to write this for better readability.
If you have a function like below,
void animal(bool hasFourLegs, bool hasHead, bool hasBody);
When you call the function, you will end up with something like
animal(true, false, true);
and this makes me go take a look at the definition every time I encounter function like this.
SO...
I do something like this!
const bool HAS_FOURLEGS = true;
const bool NO_HEAD = false;
const bool HAS_BODY = true;
animal(HAS_FOURLEGS, NO_HEAD, HAS_BODY);
But I do not like to declare const bool every time I call the function.
It seems like CPP does not support something like
animal(bool hasFourlegs = true, bool hasHead = false, bool hasBody = true);
Is there any better and shorter way?

When I run into issues related to this I sometimes create an enum even when there are only 2 expected choices:
For example, instead of the following function declaration:
bool search(..., bool recursive);
I'd go with:
enum class SearchOpt
{
Recursive,
NonRecursive
};
bool search(..., SearchOpt opt);
Therefore, the calling syntax changes from:
bool found = search(..., true);
to:
bool found = search(..., SearchOpt::Recursive);
Note: this avoids you having to create your own constants every time you call the function.
Edit
As others have suggested, instead of having separate bools for each option and thereby a separate enum for each it would make sense to have a single enum configured as bit flags.

Use flags:
enum {
HAS_LEGS = 0x01,
HAS_HEAD = 0x02,
HAS_BODY = 0x04,
};
void animal(int properties);
animal(HAS_LEGS | HAS_HEAD);

One other option is to use a class to hold the parameters where they're closely related:
struct AnimalOptions {
bool hasHead, hasBody, hasLegs;
AnimalOptions() : hasHead(false), hasBody(false), hasLegs(false);
}
...
AnimalOptions opt;
opt.hasHead = true;
animal(opt);
This technique is useful whenever you have a function which seems to take a bunch of parameters with identical types, whose order isn't easily remembered. It's just as useful when your function take several ints.

As a alternative to the other answers, I liked tagged_bool that Andrzej Krzemieński came up with on his blog.

Strange no one suggested named parameters from Boost.parameter: http://www.boost.org/doc/libs/1_59_0/libs/parameter/doc/html/index.html

Comments are your friends!
animal( true, //hasFourLegs
false, //hasHead
true //hasBody
);

You could use bitwise values, as follows:
const int hasLegs = 0x01;
const int noHead = 0x02;
const int hasBody = 0x04;
Then call animal with any combination of the above, e.g.:
animal(hasLegs + hasBody);
Decalre animal with a single int parameter.
inside `animal`, test the bits:
if (parameter & haasBody)
{
// it has a body....
}

C++20 has designated initializers as part of aggregate initialization. You could make a struct with the boolean parameters and pass the struct by value. You can even have default parameter values.
struct AnimalParts {
bool hasFourLegs = false;
bool hasHead = true;
bool hasBody = true;
}
void animal(AnimalParts parts);
Then use it like this:
animal({.hasFourLegs = true, .hasHead = false});
This comes very close to the named parameters idiom you suggested. In terms of compilation both options seem to produce comparable output, see on Godbolt.

I'm not sure it's a correct way to go, but still I cannot resist sharing this thought.
Let's imagine the function is not yours, but rather from some popular API which is hard to change.
void animal(bool hasFourLegs, bool hasHead, bool hasBody);
In this case it's possible to call it like this:
animal(bool("hasFourlegs"), !bool("hasHead"), bool("hasBody"));
The C-string is always a non zero pointer, which is converted to true.
One possible downside is compilation time...?
Another is increase in length of code rows...

Related

How can i use bool to create a file

Hi can someone help me with this function:
bool createfile (string path);
It is supposed to create a file but my problem is:
What exactly the true or false have to do with creating a file?! How can I use it?
The bool is the return type of the function createfile(). Without the definition it is impossible to tell for sure what exactly this value is supposed to be, but often it is used to return if the function was successful in doing what it is supposed to do, in this case, create a file.
What exactly the true or false have to do with creating a file?!
You might want to return true if the file was successfully created or false otherwise.
How can I use it?
This depends on the body of the function and the purpose that you want to use the function for.
Quick answer
To directly answer the "How can I use it" part of your question:
You call it this way:
string path = "/path/to/my/file.txt";
bool returnedValue = createfile(path);
As for "What exactly the true or false have to do with creating a file?!", like mentionned in the other answers, it might indicate the success or failure of the operation, but you might want to double-check that, because the actual value will depend on the implementation of bool createfile(string path)...
Comprehensive answer
It seems you need some help interpreting the syntax of bool createfile(string path);
What we need to clarify here is that in c++ (and many other languages), the first word used in the function declaration is the return type.
You could compare this to some arbitrary mathematical function of the following form: here
x = a + b
In this case, x is the result of the addition function.
Assuming all the elements above are numbers, we could translate this in c++, like so:
int a = 0;
int b = 5;
int x = a + b;
We could extract the example above in a function (to reuse the addition), like so:
int add(int a, int b)
{
return a + b;
}
and use it in the following way (with a main to put some execution context around it):
int main()
{
int x = add(0,5);
return 0;
}
Here are some other examples of functions:
// simple non-member function returning int
int f1()
{
return 42;
}
// function that returns a boolean
bool f2(std::string str)
{
return std::stoi(str) > 0;
}
You'll find more details here. It might seem like a lot to take in (the page is dense with information), but it is a true reference.

How to elegantly implement single methods with variable output?

I am trying to improve my code style.
Sometimes I have methods that do complicated checks or computations and depending on the context of the calling method I need different results from these algorithms. Let's assume that there is one result, that is always needed and it will be the return value of the method. But how to deal with the optional other results? Of course I want to implement my complicated method only once. Therefore I have introduced modifiable reference parameters and depending on some conditions they are overwritten with these additional results.
As a convenience for those contexts where I don't need the additional results, I have introduced overloads that create dummy variables that are passed to the single implementation.
Please see the following simplified example code:
#include <iostream>
/**
* \brief Checks whether everything is okay.
*
* \param isCheckedFirstTime if point is not null, it will be overwritten with
* whether this method has been called for the first time
*
* \returns okay or not
*/
bool isOkay(bool*& isCheckedFirstTime)
{
static bool isFirstTime = true;
if (nullptr != isCheckedFirstTime)
{
*isCheckedFirstTime = isFirstTime;
}
isFirstTime = false;
return true;
}
/**
* \brief Checks whether everything is okay.
*
* \returns okay or not
*/
bool isOkay()
{
bool* dummy = nullptr;
return isOkay(dummy);
}
int main()
{
const bool okay = isOkay();
std::cout << "Is everything okay?: " << okay << std::endl;
return 0;
}
Obviously I could get rid of a lot of boilerplate code by adding a default value for the parameter isCheckedFirstTime like this
bool isOkay(bool*& isCheckedFirstTime = nullptr)
which is not legal, because I cannot bind a non-const lvalue reference to an rvalue of the corresponding type.
Is there a workaround for that? Or is there another possibility to have only one method doing all the computations without overloads for different outputs and without having to declare dummy paramters in the calling code?
One solution I could think of is packing all possible results into one std::tuple. Then the caller can use what he wants. But it might have a disadvantage, if calculation of optional results is costly. Then having a condition (like nullptr != ...) saves computation time if nobody needs the result.
I am looking forward to your proposals!
Usually this is done by returning std::tuple.
In your case it will look something like:
std::tuple<bool,bool> isOkay()
{
static bool isFirstTime = true;
bool isCheckedFirstTime = isFirstTime;
isFirstTime = false;
return std::make_tuple(true, isCheckedFirstTime);
}
In case when you need to return optional complex object or you don't want to calculate unneeded value, it's better to use std::optional if you can use C++17.
std::tuple<bool,std::optional<bool>> isOkay(bool needCheckFirstTime = false)
{
static bool isFirstTime = true;
std::optional<bool> isCheckedFirstTime;
if (needCheckFirstTime) {
isCheckedFirstTime = isFirstTime;
}
isFirstTime = false;
return std::make_tuple(true, isCheckedFirstTime);
}
Therefore I have introduced modifiable reference parameters and depending on some conditions they are overwritten with these additional results.
Out parameters should be avoided like plague. If a function produces a result, it should be a part of its return type. So how we figure out such type for your case?
You've suggested a tuple; in this case, a struct or a tuple would work well.
But it might have a disadvantage, if calculation of optional results is costly.
Sure, but there's nothing that says you have to necessarily tie the arguments to the results. A function could take a bitset or similar enumeration telling it exactly what to compute, and return a struct full of optional values. The specific will largely depend on the specific case being solved.
It appears that you're in doubt whether isCheckedFirstTime should be a pointer or a reference, so you made it both. That's just inconvenient.
This might be more expressive:
bool isOkay(std::optional<bool>& isCheckedFirstTime)
{
static bool isFirstTime = true;
if (isCheckedFirstTime)
{
*isCheckedFirstTime = isFirstTime;
}
isFirstTime = false;
return true;
}
bool isOkay()
{
std::optional<bool> dummy;
return isOkay(dummy);
}

add a parameter or add a function?

I always meet such a problem when coding.
there is a interface named "INetworkReader", which looks like:
struct INetworkReader
{
virtual void readFile(const std::string& url) = 0;
...
};
Now, I wanted to expand the readFile() function, the readFile() function need setting a timeout or something else to realize more controls, so Now I has two solutions.
solution 1(add a default parameter):
struct INetworkReader
{
virtual void readFile(const std::string& url, int timeout = 0) = 0;
...
};
solution 2(add another function):
struct INetworkReader
{
virtual void readFile(const std::string& url) = 0;
virtual void readFileTimeout(const std::string& url,int timeout) = 0;
...
};
I prefer the solution 1 for that it's parameter describe it's action clearly, the only disadvantage I think is that it increase the number of parameter.
So, as you see, which looks better? why?
I found another case which could be more complicated, look the following code.
struct IComputer
{
virtual bool addMouse(/* in */const std::string& mouseID, /*out*/ IMouse** ppMouse ) = 0;
}
Now want to add a parameter to tell if it's adding to a USB port, these are still has two solutions.
solution 1(add a default parameter):
struct IComputer
{
virtual bool addMouse(/* in */const std::string& mouseID, /*out*/ IMouse** ppMouse, /* in */ bool USBPort = true ) = 0;
}
solution 2(add another function):
struct IComputer
{
virtual bool addMouse(/* in */const std::string& mouseID, /*out*/ IMouse** ppMouse ) = 0;
virtual bool addMouseNotUSB(/* in */const std::string& mouseID, /*out*/ IMouse** ppMouse ) = 0;
}
this time I prefer the second for that the first solution has broken sequence of in-out parameter.
so, two case, four solutions, which one is better? why?
IMO I prefer solution 2 (as long as it takes a timeout parameter). If you face the code for the first time, you'll quickly understand what '1000' is in the expression readFileTimeout(url, 1000), rather than in readFile(url, 1000). In the second expression one could think the code is reading 1000 bytes, for example.
In the second case, I also prefer using different function names, but since we're passing a boolean, I'd use function names from which one can deduce the boolean value:
addMouse(const std::string& mouseID, IMouse** ppMouse) //For non-USB mice
addUSBMouse(const std::string& mouseID, IMouse** ppMouse) //For USB mice
The decision of using inverse logic or not (i.e. creating addNonUSBMouse instead of addUSBMouse) is arbitrary and depends on the cases your code is likely going to run. If in most cases mice are not USB, use my proposal. Otherwise use the inverse logic version.
My lemma is: try naming functions the way it would be unnecessary to read their prototypes.
Yet another option is to use types to force expressiveness in the calling code:
struct INetworkReader
{
virtual void readFile(const std::string& url, Timeout timeout = Timeout::Infinite) = 0;
...
};
Calling code might be:
p->readFile(url, Timeout{200, Timeout::ms});
Mote that a Timeout of 0 is a bit ambiguous: it might mean a non-blocking check for data, or it might block indefinitely, so a value like Infinite or Never is clearer.
With C++14 you could create an explicit Timeout constructor from a std::chrono::duration such as 200ms.
For the mouse example:
enum Connection { USB, NonUSB };
virtual std::pair<bool, IMouse*> addMouse(const std::string& mouseID,
Connection connection = USB ) = 0;
Notice that for the in / out parameter problem, I've returned all outputs rather than taking an IMouse**? You could return a tuple, pair or custom struct.
Solution 1 is preferred. It's definitely OK for a function to contain two parameters. Just consider other solutions(such as the Builder Pattern for too many parameters for constructors) when there are too many parameters.

Mixing pointers to const structs in C++ classes -- declaring a struct on the arguments list?

I'm developing for an embedded hardware using C++ and I often use pointers to const (ROM) structs to minimize the object sizes.
When I get a pointer passed to my class constructor, I want the compiler to create another ROM object based on the one I passed but with one or two arguments changed and just then call the parent class constructor (Display_Element). Any ideas of how this could be done?
Since a const string can be declared within a parameter list I though possibly there could be a way of also declaring a const struct within a parameter list.
I wanted to do something like this, (which is illegal in C++)
Button::Button(const Colors_const* ecc, const Display_element_const* edc, const Element_const* eec, char* elabel,
Display_element* eparent, Screen* escreen) :
Display_element(ecc, cc,Display_element_const {
edc->xi+200,
edc->xf,
edc->yi,
edc->yf,
edc->font_size,
edc->image,
edc->image_x_offset,
edc->image_y_offset,
edc->label_x_offset,
edc->label_y_offset,
edc->mouse_down_ptr,
NULL,
edc->largura_borda_externa,
edc->borda_panel
},
eec,elabel,eparent,escreen) {
flags.largura_borda = 2;
//flags.largura_borda_externa = 3;
flags.borda_light_shadow = true;
flags.sliding_text = true;
flags.dont_paint_on_click = false;
}
Thanks
Well, it seems what I want to do is really illegal and can't be done in C. But philosophically I keep asking myself: if I can allocate a const char[n] written inside a parameter list such as fn(...,"The brow dog",...) why not a way to allocate a const struct the same way? If someone knows the answer, please post!
The workaround I found is to do it the canonical way: declare a const struct and then later assign the appropriate pointer to the struct (something I wanted to be done inside Display_element function on the first place). It solves my problem, but not the conceptual question I've been trying to formulate...
const Display_element_const new_ec = {
edc->xi+200,
edc->xf,
edc->yi,
edc->yf,
edc->font_size,
edc->image,
edc->image_x_offset,
edc->image_y_offset,
edc->label_x_offset,
edc->label_y_offset,
edc->mouse_down_ptr,
NULL,
edc->largura_borda_externa,
edc->borda_panel
};
Button::Button(const Colors_const* ecc, const Display_element_const* new_edc, const Element_const* eec, char* elabel,
Display_element* eparent, Screen* escreen) :
Display_element(ecc, edc,eec,elabel,eparent,escreen) {
//previously dc = edc, assigned inside Display_element fn
dc = &new_ec;

How to make sure a function is only called once

Suppose I have a function named caller, which will call a function named callee:
void caller()
{
callee();
}
Now caller might be called many times in the application, and you want to make sure callee is only called once. (kind of lazy initialization), you could implement it use a flag:
void caller()
{
static bool bFirst = true;
if(bFirst)
{
callee();
bFirst = false;
}
}
My opinion for this is it needs more code, and it needs one more check in every call of function caller.
A better solution to me is as follow: (suppose callee returns int)
void caller()
{
static int ret = callee();
}
But this can't handle the case if callee returns void, my solution is using the comma expression:
void caller()
{
static int ret = (callee(), 1);
}
But the problem with this is that comma expression is not popular used and people may get confused when see this line of code, thus cause problems for maintainance.
Do you have any good idea to make sure a function is only called once?
You could use this:
void caller()
{
static class Once { public: Once(){callee();}} Once_;
}
Thread-safe:
static boost::once_flag flag = BOOST_ONCE_INIT;
boost::call_once([]{callee();}, flag);
You could hide the function through a function pointer.
static void real_function()
{
//do stuff
function = noop_function;
}
static void noop_function()
{
}
int (*function)(void) = real_function;
Callers just call the function which will do the work the first time, and do nothing on any subsequent calls.
Your first variant with a boolean flag bFirst is nothing else that an explict manual implementatuion of what the compiler will do for you implictly in your other variants.
In other words, in a typical implementation in all of the variants you pesented so far there will be an additional check for a boolean flag in the generated machine code. The perfromance of all these variants will be the same (if that's your concern). The extra code in the first variant might look less elegant, but that doesn't seem to be a big deal to me. (Wrap it.)
Anyway, what you have as your first variant is basically how it is normally done (until you start dealing with such issues as multithreading etc.)
Inspired by some people, I think just use a macro to wrap comma expression would also make the intention clear:
#define CALL_ONCE(func) do {static bool dummy = (func, true);} while(0)