What is the term for overloading to cover optional parameters - overloading

Is there a term for the technique of overloading to create optional parameters? "Helper Method" comes to mind but doesn't seem appropriate
foo(var x)
{
foo(x, new var());
}
foo(var x, var y);

It's called overloading.

Related

Trailing return type in non-template functions [duplicate]

This question already has answers here:
Should the trailing return type syntax style become the default for new C++11 programs? [closed]
(4 answers)
Closed 2 years ago.
I have seen people using the following syntax to implement functions:
auto get_next() -> int
{
/// ...
}
Instead of:
int get_next()
{
/// ...
}
I understand both and I know that the trailing return type syntax is useful for template code using decltype. Personally I would avoid that syntax for other code since when reading code I prefer to read the concrete return type of a function first, not last.
Is there any advantage in using the trailing return type syntax for non-template code as shown above (except personal preference or style)?
In addition to sergeyrar's answer, those are the points I could imagine someone might like about trailing return types for non-template functions:
Specifying a return type for lambda expressions and functions is identical w.r.t. the syntax.
When you read a function signature left-to-right, the function parameters come first. This might make more sense, as any function will need the parameters to produce any outcome in the form of a return value.
You can use function parameter types when specifying the return type (the inverse doesn't work):
auto f(int x) -> decltype(x)
{
return x + 42;
}
That doesn't make sense in the example above, but think about long iterator type names.
One potential benefit is that it makes all of your declared function names line up:
auto get_next(int x, int y) -> int;
auto divide(double x, double y) -> double;
auto printSomething() -> void;
auto generateSubstring(const std::string &s, int start, int len) -> std::string;
source: https://www.learncpp.com/cpp-tutorial/the-auto-keyword/
Well you already mentioned the major use case of the trailing return type. It's usage if the return type depends on the arguments.
If we exclude that use case the only advantage you might gain is an enhanced readability of your code, especially if your return type is a bit more complex, but you don't have a technical benefit of using the trailing return in that scenario.

Why is it called operator overloading?

If the following class, Foo, is defined. It is said it overloads the unary ampersand (&) operator:
class Foo {
public:
Foo* operator&() { return nullptr; }
};
I think in this case, (reglardless of the fact that you can get the address of such an object by means of std::addressof() and other idiomatic tricks) there is no way to access/choose the original unary ampersand operator that returns the address of the object called on, am I wrong?
By overloading however, I understand that there is a set of functions of which one will be selected at compile-time based on some criteria. But this thinking doesn't seem to match the scenario above.
Why is it then called overloading and not something else like redefining or replacing?
Consider the following code:
int x;
Foo y;
&x; // built-in functionality
&y; // y.operator&();
We have two variables of different types. We apply the same & operator to both of them. For x it uses the built-in address-of operator whereas for y it calls your user-defined function.
That's exactly what you're describing as overloading: There are multiple functions (well, one of them is the built-in functionality, not really a "function") and they're selected based on the type of the operand.
You can't redefine a function or operator in C++, you can add only new use to it, defining new set of arguments. That's why it called overloading instead of redefining.
When you overload operator as a member of class you
1) defined it with first argument supposed to be an instance of that class
2) gave it access to all members of that class.
There are still definitions of operator& with different arguments and you have a non-zero chance to create situation where use of operator would be ambigous.

Function Composition Operator

As a small exercise in functional programming in C++, I want to overload the operator* to allow me to compose 2 functions.
What stumps me is that if I define my operator like this:
std::function<float(float)> operator*(std::function<float(float)> func1, std::function<float(float)> func2)
{
// ...
}
I cannot use it with regular functions as in:
float f(float);
float g(float);
auto composite = f*g;
Because I get:
error: invalid operands of types ‘float(float)’ and ‘float(float)’ to binary ‘operator*’
If I try to add a function pointer only version as in:
std::function<float(float)> operator*(float(*func1)(float) , float(*func2)(float))
{
return [func1, func2](float x) { return func1(func2(x)); };
}
I get this error:
error: ‘std::function<float(float)> operator*(float (*)(float), float (*)(float))’ must have an argument of class or enumerated type
I was able to get it to work by adding a make_function helper, but that really makes the code ugly.
Is there a way to get this operator to automatically cast functions to std::function instances?
Unfortunately, C++ does not allow operators to be overloaded for built-in types. Just as you cannot implement your own operator* for two ints, you cannot implement it for two function pointers, except if you represent these functions with the std::function type which is a class and therefore not a built-in type.
You can, however, instead of using an operator, simply use a function:
std::function<float(float)> dot(float(*func1)(float) , float(*func2)(float))
{
return [func1, func2](float x) { return func1(func2(x)); };
}

Two parentheses after variable?

I have something like this in one method
autoPtr<LESModel> LESModel::New
95 (
96  const volVectorField& U,
97  const surfaceScalarField& phi,
98  transportModel& transport,
99  const word& turbulenceModelName
100 )
101 {
...
122 dictionaryConstructorTable::iterator cstrIter =
123  dictionaryConstructorTablePtr_->find(modelType);
...
143 return autoPtr<LESModel>
144  (
145  cstrIter()(U, phi, transport, turbulenceModelName)
146  );
147  }
If I am right cstrIter is a variable of class dictionaryConstructorTable::iterator (could not find this class though) and beginning with line 143 the constructor autoPtr<LesModel> is called and the result returned. The parentheses after the constructor autoPtr<LESModel> therefore should be parameters and since cstrIter is a variable I am wondering what the two parentheses after the variable mean. Perhaps I am misreading something?
C++ supports 'operator overloading', meaning you can define types that support syntax like a + b. This works by defining functions with names such as operator+. When an overloadable operator is used with a user defined type C++ looks for functions with these special names and, if a suitable function is found, treats the operator as a function call to the function.
One of the operators that one can overload is the function call operator. A member function named operator() will be called when you use an object name as though it's a function:
struct S {
void operator() (void) {
std::cout << "Hello, World!\n";
}
};
int main() {
S s;
s(); // prints "Hello, World!\n"
}
It looks like dictionaryConstructorTable::iterator overloads the function call operator and returns some type that also overloads the function call operator (or just uses the built-in operator).
Replacing the use of the function call operator with normal member functions may make it clearer what's happening:
return autoPtr<LESModel>( cstrIter.foo().bar(U, phi, transport, turbulenceModelName));
This looks like OpenFOAM, which has its own hash table implementation.
If you look in src/OpenFoam/containers/HashTable/HashTable/HashTable.H, line 454 (at least in my copy), you'll find that iterator overloads operator() and operator* to return a reference to the iterator's currently referenced value.
To clarify a little, C++ allows you to overload many of the operators you use to provide domain-specific functionality. This allows for, say, vector.add(otherVector) to use the "obvious" syntactic sugar of vector + otherVector instead. The downside is that what is obvious is not always so obvious, as this question demonstrates.
This construction
cstrIter()(U, phi, transport, turbulenceModelName)
means that at first a temporary object of type cstrIter is created using the default constructor
cstrIter()
And after that the function call operator is used for this object
cstrIter()(U, phi, transport, turbulenceModelName)
That it would be more clear you could rewrite the expression the following way
cstrIter obj;
obj(U, phi, transport, turbulenceModelName);

Operator- overloading (same parameters, different return type)

How do I overload the minus operator accepting the same number of parameters, but having different return types?
Template class:
template <typename T>
T minus (T x, T y) {
return (x - y);
}
template <typename T>
double absMinus (T x, T y) {
double sd = abs(x - y);
return sd;
}
Operator overloading class:
Minus operator-(Minus &p, Minus &q) {
return (p.something - q.something);
}
double operator-(Minus &p, Minus &q) {
return (p.something() - q.something());
}
When I tried to compile, it gave me the following error:
Minus.h:25: error: new declaration ‘double operator-(Minus&, Minus&)’
Minus.h:24: error: ambiguates old declaration ‘Minus operator-(Minus&, Minus&)’
No, you can't. Overloading can be done only when the parameter list is different. For example:
int myFun(int);
double myFun(int);
Now you are calling myFun(10). Compiler has no way to determine which version to call.
You cannot, overload resolution chooses an overload based only on the types of function parameters.
Operator overloading is just an extension of function/method overloading. For function overloading, the signature of the functions should be different. As reported in your post, the signatures of the two functions are the same.
Please note that function/method signature doesn't include the return type.
Read this for more on this topic here: Java - why no return type based method overloading?