Trigger event on return in C++ - c++

I want to execute some function right before the return of another function. The issue is that there are multiple returns and I don't want to copy-paste my call before each of them. Is there a more elegant way of doing this?
void f()
{
//do something
if ( blabla )
return;
//do something else
return;
//bla bla
}
I want to call g() before the function returns.

struct DoSomethingOnReturn {
~DoSomethingOnReturn() {
std::cout << "just before return" << std::endl;
}
};
...
void func() {
DoSomethingOnReturn a;
if(1 > 2) return;
}

There are some ways to do this.
One would be to use boost::scope_exit or use a struct and do your work in the destructor.
I dislike the preprocessor syntax of boost and I am too lazy to write struct so I prefer using a boost::shared_ptr or on newer compilers a std::shared_ptr. Like this:
std::shared_ptr<void>(nullptr, [](void*){ /* do your stuff here*/ });

This is often a sign that instead of trying to artificially do something before every return, you should try to refactor your function into single-exit form. Then it's super easy to do your extra step because...there's only one return.

I think try-finally statements will do what you want.
void f()
{
__try
{
//do something
if ( blabla )
return;
//do something else
return;
//bla bla
}
__finally
{
g();
}
}
The try-finally statement is a Microsoft extension to the C and C++
languages that enables target applications to guarantee execution of
cleanup code when execution of a block of code is interrupted. Cleanup
consists of such tasks as deallocating memory, closing files, and
releasing file handles. The try-finally statement is especially useful
for routines that have several places where a check is made for an
error that could cause premature return from the routine.
Quoted from msdn.

#define RETURN_IT g(); \
return;
void f()
{
//do something
if ( blabla )
RETURN_IT;
//do something else
RETURN_IT;
//bla bla
}
Simple, although I do kind of like loki's suggestion

For this kind of thing, you could simply use a boolean. That way you don't have too many if/else statements:
void f()
{
//do something
done = false;
if ( blabla )
done = true;
//do something else
if (!done) {
// some code
done = true;
}
if (!done) {
// some other code
done = true;
}
return;
}

void f()
{
//do something
if ( blabla )
return;
//do something else
return;
//bla bla
}
void f_callg()
{
f();
g();
}
If there is no access to where f() is called from
void f_copy_of_old()
{
//do something
if ( blabla )
return;
//do something else
return;
//bla bla
}
void f()
{
f_copy_of_old();
g();
}

int g() {
// blah
return 0;
}
void f() {
// do something
if (blabla)
return g();
// do something else
return g();
}

Related

how can I allow a method parameter to be null

I'm new to c++, and coming from c#;
in c# to achieve my intended goal I would simply do this
public void MyMethod(int? value) {
if(value is null) {
// Do something
} else {
// Do something else
}
}
how might I achieve this result, if possible in c++?
You can do this with std::optional.
void MyMethod(const std::optional<int>& option) {
if(option.has_value()) {
// Do something with the int option.value()
} else {
// Do something else with no value.
}
}
std::nullopt is what you pass when no value is desired. MyMethod(std::nullopt);
Or if you want to be able to omit the argument entirely and say MyMethod() then you can make the argument default to std::nullopt.
void MyMethod(const std::optional<int>& option = std::nullopt) {
This sounds like a job for overloading:
void f() {
// do something for no argument
}
void f(int i) {
// do something with I
}

Checking same if condition to series of functions

lets say for example i have the following code:
bool foo1() {
check something...
}
void foo2() {
do something ...
}
void foo3() {
do something ...
}
void foo4() {
do something ...
}
void foo5() {
do something ...
}
void foo6() {
if (foo1()) foo2();
if (foo1()) foo3();
if (foo1()) foo4();
if (foo1()) foo5();
}
is there a better way to do this? i don't want to write the if statement every time, but each of the other functions might change the calculation of foo1().
i have a series of different functions and i want it to use foo1() before every call.
You could put the functions in a container and then use a loop:
std::vector<void (*)()> functions = {foo2, foo3, foo4, foo5};
for (auto f: functions)
if (foo1())
f();

Avoid if-else statement with template function

If I have some code like this:
void function_1(...)
{
//do something
}
void function_2(...)
{
//do something
}
int function_3(...)
{
//do something
}
int main()
{
....
if (CONSTANT_1) function_1()
else if (CONSTANT_2) function_2()
else if (CONSTANT_3) function_3()
....
}
I would like avoid the if-else statement and do something like this in main function:
int main()
{
function<CONSTANT>();
}
How can I avoid the use of if-else statement and simulate this behavior?
In general you can specialize the function template:
template<int N>
void function();
template<>
void function<1>()
{
//do something
}
template<>
void function<2>()
{
//do something
}
template<>
void function<3>()
{
//do something
}
This works, but there might be better solutions as well.
Overload and tag dispatch. The Base template will convert the constant into a unique type. Then simple overload resolution will choose the proper overload. This is all assuming the constant are constexpr, and not something known only at run-time.
void function(std::integral_constant<int, CONSTANT_1>)
{
//do something
}
void function(std::integral_constant<int, CONSTANT_2>)
{
//do something
}
int function(std::integral_constant<int, CONSTANT_3>)
{
//do something
}
template<int constant>
auto function()
{
return function(std::integral_constant<int, constant>{});
}
int main()
{
function<CONSTANT_2>(); // calls the second overload
}
The above has the benefit of issuing a compile time error when an overload isn't found, as opposed to a linkage error if you specialize template functions instead.

Nested try/catch blocks for error propagation across classes?

I have a class interface function which implements other functions within the class in a specific order:
class Child
{
public:
auto Interface()->bool
{
this->F1(); //I use this just for extra clarity (e.g. not calling global function)
this->F2();
return true;
}
auto F1()->void
{
//Do stuff...
}
auto F2()->void
{
//Do more stuff...
}
};
class Parent
{
public:
Child ChildObj;
auto CallUponChild()->void
{
bool success = ChildObj.Interface();
}
};
I want to wrap the 'Interface()' implementation in a try/catch block:
auto Interface()->bool
{
try{
this->F1();
this->F2();
}catch(...){
//Handle
}
}
However, on the occurance of an error, I wish to attempt the function again, and if that errors, I want to propogate the error back to the Parent class:
auto Interface()->bool
{
int error_count=0;
try{
try{
this->F1();
this->F2();
return true;
}catch(...){
if(error_count<1){this->F1(); this->F2();}
else{throw "Out of tries";}
}
}catch(...){
return false;
}
}
Is using nested try/catch blocks fround upon? Is this the best approach to take?
Something like
auto Interface()->bool
{ int error_count=0;
while (error_count < 1) {
try {
this->F1();
this->F2();
return true;
}
catch(...){
// if (error_count >= 1)
// throw; // to throw original exception
++error_count;
}
};
// throw "Out of tries"; // to throw "Out of tries" exception
return false; // to use the boolean result
}
should be sufficient. If F1() throws an exception in your catch block, your function will return false without incrementing error_count.
It does not seems to be something that the child should handle imho, should that behaviour been handled by the Parent which knows how to deal with their childs? I would go this way:
auto CallUponChild()->void
{
const bool success = ChildObj.Interface();
if (!success) { // maybe if-init if you have a c++17 compiler
// try again
ChildObj.Interface();
}
}
I think the way to handle the child objects should be at Parent level as I said, Child object should do one thing and if it's needed to be done twice(or N) then should'n be their responsibility.
If you want to show how the exception were thrown you can have a look at this:
http://en.cppreference.com/w/cpp/error/throw_with_nested

Mutex/Lock with scope/codeblock

I remember seeing it in some conference, but can't find any information on this.
I want something like:
lock(_somelock)
{
if (_someBool)
return;
DoStuff();
} // Implicit unlock
Instead of:
lock(_somelock);
if (_someBool)
{
unlock(_somelock);
return;
}
DoStuff();
unlock(_somelock);
As you can see the code gets very bloated with multiple early returns.
Obviously one could make another function to handle locking/unlocking, but it's a lot nicer no?
Possible with C++11 standard library?
Yes, you can use a std::lock_guard to wrap a mutex.
{
std::lock_guard<std::mutex> lock(your_mutex);
if (_someBool)
return;
DoStuff();
}
The standard idiom is to use a guard object whose lifetime encompasses the locked state of the mutex:
std::mutex m;
int shared_data;
// somewhere else
void foo()
{
int x = compute_something();
{
std::lock_guard<std::mutex> guard(m);
shared_data += x;
}
some_extra_work();
}
You can simply create an autolock of your own.
Class AutoLock
{
pthread_mutex_t *mpLockObj;
AutoLock(pthread_mutex_t& mpLockObj)
{
mpLockObj = &mpLockObj;
pthread_mutex_lock(mpLockObj);
}
~AutoLock()
{
pthread_mutex_unlock(mpLockObj);
}
};
use like:
#define LOCK(obj) AutoLock LocObj(obj);
int main()
{
pthread_mutex_t lock;
LOCK(lock);
return 0;
}