0

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
    You're making this too complicated. Firstly, `B::vec` should be an argument to `B::func_B` (consistency with `A`). Then `a_ptrs` cannot be a reference, and you have some `const` qualifiers missing in function parameter types. – LogicStuff Sep 03 '17 at 21:41
  • Why do you have reference members? – Cheers and hth. - Alf Sep 03 '17 at 21:43
  • @LogicStuff, yes, you're right, `B::vec` should be an argument to `B::func_B`. Why can't I have `a_ptrs` as a reference? What's the alternative? I'm trying not to have any copies of `class A`. – Pafnuty Sep 03 '17 at 22:28
  • @Cheersandhth.-Alf the only reason I have reference members is to avoid having any copies of class A. The one reference that I have trouble with is constant, so I don't want to change it, but just use it. So what is the alternative to reference memebers. And what do you suggest? – Pafnuty Sep 04 '17 at 08:11

1 Answers1

0

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) {}
};