Part 7 - function signatures
In this part I'll visit function signatures and describe what types your arguments should have.
It's always better to look at an example. Let's say we have a function that will say if red is dominant color in pixel from position x
and y
on screen.
bool is_red(int x, int y);
bool is_red(int& x, int& y);
bool is_red(const int& x, const int& y);
bool is_red(int* x, int* y);
bool is_red(const int* x, const int* y);
void is_red(int x, int y, bool& result);
// I could go on and on...
But we have to begin somewhere.
return type
In C it's common for functions to return data via function arguments.
bool do_something(int arg1, int& value);
// returned bool is actually saying if function succeeded or not
// returned value is stored in "value" argument
This is due to pathetic limitations of C. In C++ we don't have to do such things due to std::tuple
deconstruction. This concludes that our function should return what we want to return => bool
.
One may ask: "what if I want to return optional?" And that is a very good question. You can wrap your return type in std::optional
. However, std::expected
is soon to be added (as of writing this article) and provides even better way of returning optional values, because it allows to provide a "reason why call failed" well. It can easily be added to your project by using github.com/TartanLlama/expected.
auto optional_return(const bool& arg) {
return arg ? std::optional<std::string>{"Value"} : std::nullopt;
}
argument types
Assuming we plan to pass object of type T
as our argument, we can pass it as:
T
- "performs a copy and pass copied object to function" This will become costly if you attempt to copy e.g. png texture.const T
- "performs a copy, but now you can't modify the object." Why would you ever do this?T*
- "optional parameter, that will modify (object) inside of function". If you plan to modify the pointer itself, you have to remember, that you get a copy.const T*
- "optional parameter, will not modify (object)" Here, your compiler is allowed to optimize away the copy, which means it will pass exactly the same pointer (without any copies).T&
- "required parameter, will modify (object)"const T&
- "required parameter, will not modify (object)" Just as withconst T*
compiler is allowed to optimize away additional copies.T&&
- "you have been granted full ownership of this argument"const T&&
- just why?
summing up
-
returning or argument?
-
returning
-
return can fail?
-
YES
-
NO
-
T
-
-
-
-
argument
-
passing ownership?
-
YES
-
T&&
-
-
NO
-
is it mandatory?
-
YES
-
need to mutate?
-
YES
-
T&
-
-
NO
-
const T&
-
-
-
-
NO
const T*
-
-
-
-
-
(Yes, this whole graf is done using CSS only)