Initialization of an optional constant reference in a class

866 views Asked by At

I have two classes, A and B. Class A is a transformation (a matrix) that performs a transformation on a given vector.

class A{ 
public:
     ...
     A(...){};
     ...
     void func_A(std::vector<double>& vec){
        /* Transform vector vec */
     }
};

Class B has two members; std::vector<double> &vec a reference of a vector, and const std::vector<std::shared_ptr<A> > &a_ptrs a constant reference of another vector containing shared pointers of class A, representing different transformations. a_ptrs may contain zero, one or several transformations. One of the jobs of class B is to apply these (if any) transformations on vector vec.

class B{
public:
    std::vector<double> &vec;
    const std::vector<std::shared_ptr<A> > &a_ptrs;

    B(std::vector<double> &vec_ref) : vec(vec_ref){
     /* How to initialize a_ptrs if there are no transformations available? 
      That is, there are no shared pointers of class A available.*/
    }        

    B(std::vector<double> &vec_ref,
      const std::shared_ptr<A> &aptr) : vec(vec_ref){
      /* How to initialize a_ptrs if there is only one transformation available, and 
      I just decide to pass a const reference to the shared pointer of A? */
    } 

    // No issues with this constructor:
    B(std::vector<double> & vec_ref, 
      const std::vector<std::shared_ptr<A> > &aptr) : vec(vec_ref), a_ptrs(aptr){}

    void func_B(){
         ...
         // Apply the transforms:
         for(int i=0; i<a_ptrs.size(); ++i){
             a_ptrs[i]->func_A(vec);
         }
         ....
    }
};

For this purpose, as you can see, I have overloaded the constructor of class B. When const std::vector<std::shared_ptr<A> > &a_ptrs is passed as argument to the constructor of B, everything is fine. But my problem is that I simply don't know how to initialize this constant reference for the cases where there are zero or only one transformation available, i.e., a_ptrs is empty or has only one element, respectively.

If a_ptrs has only one element, I want to be able to just pass a const std::shared_ptr<A> &aptr, and initialize a_ptrs somehow based on that.

I also don't want to make any copies of the shared pointer to class A in class B. I want to have a constant reference to the shared pointer as well.

Based on what I've found on the internet, there is a possibility of using boost::optional or std::experimental::optional, but I couldn't make it work.

I'm fairly new to c++, and I've been working on this issue for two days without any luck. How can I overcome this problem? Should I have another design strategy? I would appreciate any comments or suggestions that will help me solve this problem.

1

There are 1 answers

1
AudioBubble On

References MUST be initialized, no exceptions.

However, in your situation, you can get around this by having an empty vector at hand to handle these cases:

class B {
  static const std::vector<std::shared_ptr<A> > empty_a;

  std::vector<double> &vec;
  const std::vector<std::shared_ptr<A> > &a_ptrs;
public:

  B(std::vector<double> &vec_ref) 
    : vec(vec_ref), 
      a_ptrs(empty_a) {}
};