How can I implement a function take as some optional parameters in C++?

Viewed 133

I have a function that takes 3 determined parameters and one additional parameter.

In Matlab, I can use nargin < 4 to distinguish the case with the addtional parameter and that without the addtional parameter.

How can I implement a function in C++ imitating this behavior?

I found parameter pack / variadic parameter may be helpful, but I have no idea how to use it.

Can someone shed some info to me?

3 Answers

You can use std::optional. In the function declaration, assign the default value of std::nullopt to your optional argument. This is a special value designed to indicate that std::optional doesn't contain any value. Thus, you'll be able to call your function with 3 or 4 parameters.

void function(int a, int b, int c, std::optional<int> d = std::nullopt) {
   // check if d has value (there is a special bool conversion in std::optional)
   if (d) {
      int temp = d.value();
   }
}

int main() {
    function(0,1,2);
    function(0,1,2,3);
}

You can use parameter pack as following for similar behaviour:

#include <iostream>

//template function, takes any number of argument
template <typename... Args>
int func(Args... args)
{
    //sizeof...(args) is the number of args provided
    switch (sizeof...(args)) {
        case 4:
            std::cout << "4"; break;
        case 2:
            std::cout << "2"; break;
        default:
            std::cout << "Args: " << sizeof...(args);
    }
}

int main()
{
    func(1,2,3); //prints "Args: 3"
}

How can I implement a function in C++ imitating this behavior?

That depends on what exactly you're going to do inside that function in case of 3 actual arguments and 4 actual arguments. If those actions are very similar -- then you'd better go with the std::optional<> approach, as suggested before.

However if those actions are substantially different, then you may want to simply overload that function. I.e. have two functions with the same name: one for 3 arguments and another one for 4 arguments, with absolutely independent bodies. The compiler will be able to figure which implementation to call.

#include <iostream>

void MyFunc(int a, int b, int c)
{
    std::cout << "3-argument version called." << std::endl;
}

void MyFunc(int a, int b, int c, int d)
{
    std::cout << "4-argument version called." << std::endl;
}

int main()
{
    MyFunc(1, 2, 3);
    MyFunc(1, 2, 3, 4);
}
Related