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);
}
Related
I have a function which processes data that comes as a sequence. Because of this, I need to know the value of certain variables from the last function call during the current function call.
My current approach to doing this is to use static variables. My function goes something like this:
bool processData(Object message){
static int lastVar1 = -1;
int curVar1 = message.var1;
if (curVar1 > lastVar1){
// Do something
}
lastVar1 = curVar1;
}
This is just a small sample of the code; in reality I have 10+ static variables tracking different things. My gut tells me using so many static variables probably isn't a good idea, though I have nothing to back that feeling up.
My question: Is there a better way to do this?
An alternative I've been looking into is using an object whose fields are lastVar1, lastVar2, etc. However, I'm not sure if keeping an object in memory would be more efficient than using static variables.
Your question has a taste of being purely about style and opinions, though there are aspects that are not a matter of opinion: multithreading and testing.
Consider this:
bool foo(int x) {
static last_val = -1;
bool result = (x == last_val);
last_val = x;
return result;
}
You can call this function concurrently from multiple threads but it wont do the expected. Moreover you can only test the function by asserting that it does the right thing:
foo(1);
assert( foo(1) ); // silenty assumes that the last call did the right thing
To setup the preconditions for the test (first line) you already have to assume that foo(1) does the right thing, which somehow defeats the purpose of testing that call in the second line.
If the methods need the current object and the previous object, simply pass both:
bool processData(const Object& message,const Object& previous_message){
if (message.var1 > previous_message.var1){
// Do something
return true;
}
return false;
}
Of course this just shifts the issue of keeping track of the previous message to the caller, though thats straight-forward and requires not messing around with statics:
Object message, old_message;
while ( get_more( message )) {
processData(message, old_message);
old_message = message;
}
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.
I am working on a problem that requires me to return different return-types based on my function parameter values that I provide.
I want to do something like this --
In the code below, doSomething() is an already existing function (used by a lot of clients) which takes mode as a function parameter, and returns std::list<ReturnType> already.
Based on the mode value, I had to create another sub-functionality which returns a shared_future<std::list<ReturnType>>.
How can I change this code so that it can return one of the two return types based on the mode value?
Note: ReturnType is a template typename which we are using for the entire class.
Code:
std::shared_future<std::list<ReturnType> > futureValue() {
return functionReturningSharedFuture();
}
std::list<ReturnType> listValue() {
return functionReturningList();
}
std::list<ReturnType> doSomething(int mode) {
if(mode == 1){
// new functionality that I added
return futureValue(); // This (obviously) errors out as of now
}
else{
// already there previously
return listValue();
}
}
int main() {
doSomething(1);
return 0;
}
How can I change this code so that it can return one of the two return types based on the mode value?
Constraints and Issues:
This issue could've been easily solved by function overloading if we provide an extra function parameter (like a true value), but that extra argument is not useful, since we are already using mode. Also, it isn't considered a good design to add variables which have almost no use.
One of the major constraints is that there are clients who are already using this doSomething() expect a std::list<ReturnType>, and so I cannot return boost::any or std::variant or anything similar.
I tried using std::enable_if, but it wasn't working out since we are getting the mode value at runtime.
We can't use template metaprogramming since that would change the way our function is being called on the client-side. Something that we can't afford to do.
Thank you.
This cannot be done.
You can only have one function with a given signature. If you have calling code that already expects this to return a std::list<ReturnType>, that's it; you're done.
If you could guarantee that all existing calling code looks like
auto l = obj.doSomething(1);
then you could potentially change the return type to something which would look like a std::list to any calling code. But if there's any calling code that looks like
std::list<ReturnType> l = obj.doSomething(1);
then that's off the table.
You probably need to rethink your design here.
From the example main, I see doSomething(1);, so maybe at the call site the value of the parameter mode is always known at compile-time. In this case, one option is that you make doSomething a template<int mode> function. I'm thinking about something like this:
#include <iostream>
#include <list>
#include <vector>
// assuming you cannot change this (actually you have changed it in you example, ...)
std::list<int> doSomething(int mode) {
std::cout << "already existing function\n";
return std::list<int>{1,2,3};
}
// then you can put this too
template<int N>
auto doSomething();
template<>
auto doSomething<10>() {
std::cout << "new function\n";
return std::vector<int>{1,2,3};
}
int main() {
auto x = doSomething(3);
auto y = doSomething<10>();
}
Probably another option would be to use a if constexpr intead of if and an auto/decltype(auto) return type in doSomething, but I haven't tried it.
I have a routine that does some moderately expensive operations, and the client could consume the result as either a string, integer, or a number of other data types. I have a public data type that is a wrapper around an internal data type. My public class looks something like this:
class Result {
public:
static Result compute(/* args */) {
Result result;
result.fData = new ExpensiveInternalObject(/* args */);
return result;
}
// ... constructors, destructor, assignment operators ...
std::string toString() const { return fData->toString(); }
int32_t toInteger() const { return fData->toInteger(); }
double toDouble() const { return fData->toDouble(); }
private:
ExpensiveInternalObject* fData;
}
If you want the string, you can use it like this:
// Example A
std::string resultString = Result::compute(/*...*/).toString();
If you want more than one of the return types, you do it like this:
// Example B
Result result = Result::compute(/*...*/);
std::string resultString = result.toString();
int32_t resultInteger = result.toInteger();
Everything works.
However, I want to modify this class such that there is no need to allocate memory on the heap if the user needs only one of the result types. For example, I want Example A to essentially do the equivalent of,
auto result = ExpensiveInternalObject(/* args */);
std::string resultString = result.toString();
I've thought about structuring the code such that the args are saved into the instance of Result, make the ExpensiveInternalObject not be calculated until the terminal functions (toString/toInteger/toDouble), and overload the terminal functions with rvalue reference qualifiers, like this:
class Result {
// ...
std::string toString() const & {
if (fData == nullptr) {
const_cast<Result*>(this)->fData = new ExpensiveInternalObject(/*...*/);
}
return fData->toString();
}
std::string toString() && {
auto result = ExpensiveInternalObject(/*...*/);
return result.toString();
}
// ...
}
Although this avoids the heap allocation for the Example A call site, the problem with this approach is that you have to start thinking about thread safety issues. You'd probably want to make fData an std::atomic, which adds overhead to the Example B call site.
Another option would be to make two versions of compute() under different names, one for the Example A use case and one for the Example B use case, but this isn't very friendly to the user of the API, because now they have to study which version of the method to use, and they will get poor performance if they choose the wrong one.
I can't make ExpensiveInternalObject a value field inside Result (as opposed to a pointer) because doing so would require exposing too many internals in the public header file.
Is there a way to make the first function, compute(), know whether its return value is going to become an rvalue reference or whether it is going to become an lvalue, and have different behavior for each case?
You can achieve the syntax you asked for using a kind of proxy object.
Instead of a Result, Result::compute could return an object that represents a promise of a Result. This Promise object could have a conversion operator that implicitly converts to a Result so that "Example B" still works as before. But the promise could also have its own toString(), toInteger(), ... member functions for "Example A":
class Result {
public:
class Promise {
private:
// args
public:
std::string toString() const {
auto result = ExpensiveInternalObject(/* args */);
return result.toString();
}
operator Result() {
Result result;
result.fData = new ExpensiveInternalObject(/* args */);
return result;
}
};
// ...
};
Live demo.
This approach has its downsides though. For example, what if, instead you wrote:
auto result = Result::compute(/*...*/);
std::string resultString = result.toString();
int32_t resultInteger = result.toInteger();
result is now not of Result type but actually a Result::Promise and you end up computing ExpensiveInternalObject twice! You can at least make this to fail to compile by adding an rvalue reference qualifier to the toString(), toInteger(), ... member functions on Result::Promise but it is not ideal.
Considering you can't overload a function by its return type, and you wanted to avoid making two different versions of compute(), the only thing I can think of is setting a flag in the copy constructor of Result. This could work with your particular example, but not in general. For example, it won't work if you're taking a reference, which you can't disallow.
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...