Search code examples
c++std-functionboost-optional

Use std::function to wrap a function with optional arguments (using maybe boost::optional), and serve as a template in another class


In my recent project I want to define a class X which has an input functional in its constructor, i.e., std::function<double(const A&, const B&)>. In real applications, the argument of class B is optional (sometimes it will not have this argument). So I am trying to use the boost::optional for the second argument in my function. All of class A and B will show up as template in my class X. What is the best way to achieve this behavior I want?

I have tried:

The code for class X:

template <typename Function, typename A, typename B, typename... Args>
class X{
X(Function _f, A _a, boost::optional<B> _b){
 f_{_f};
 a_{_a};
if (_b){b_{_b};}
}
...
private: 
Function f_;
A a_;
boost::optional<B> b_;

public:
void call_function(Args... args){
  f_(args..., a_, boost::option<B> b_);
}
};

The code for the definition of function Function f and instantiation of X:

double f_example(const A_actual& a, boost::optional<B_actual> b, const OTHER& other){
...
if (b)...
}
... (declare and define instances of A_actual and B_actual and OTHER)...


X<std::function<double(const A_actual&, boost::option<B_actual>, const OTHER&)>, A_actual, boost::option<B_actual>> x(...);

Is this code correct and can achieve what I want to achieve?


Solution

  • With typo fixed, it would be

    #include <functional>
    #include <optional>
    
    
    template <typename Function, typename A, typename B, typename... Args>
    class X
    {
    public:
        X(Function f, A a, std::optional<B> b) :
          f_{f},
          a_{a},
          b_{b}
        {
        }
    
        void call_function(Args... args){
            f_(a_, b_, args...);
        }
        //...
    private: 
        Function f_;
        A a_;
        std::optional<B> b_;
    };
    

    and

    double f_example(const A_actual& , std::optional<B_actual> , const OTHER& ){
    // ...
        return 0.0;
    }
    
    void foo(const A_actual& some_a,
             const std::optional<B_actual>& some_b,
             const OTHER& some_other)
    {
        X<std::function<double(const A_actual&, std::optional<B_actual>, const OTHER&)>,
          A_actual,
          B_actual,
          const OTHER&> x(f_example, some_a, some_b);
        x.call_function(some_other);
    }
    

    Demo