How to use two constructors?

I have a code like this.

#include <iostream>
#include <vector>

using namespace std;

class AbstractValueC{
        private:
                long age = 0;
                int abs;
                bool spec = false;
        public:
                AbstractValueC() {
                        abs = 0;
                }
                AbstractValueC(int& a, bool b = false){
                        abs = *a;
                        spec = b;
                }
                AbstractValueC(int a, bool b = false){
                        abs = a;
                        spec = b;
                }
                int get_value() const {
                        return abs;
                }
                long get_age(){
                       return age;
                }
 };

int main(){
    vector<AbstractValueC> v;
    int init = 1;
    int next = 2;
    v.push_back(AbstractValueC(std::move(init)));
    cout << "I have created first v element." << endl;
    v.push_back(AbstractValueC(std::move(next)));
    cout << "I have created second v element." << endl;

    std::vector<AbstractValueC> result;
      for (auto a : v) {
          int pre = a.get_value();
          result.push_back(AbstractValueC(pre));
        }
    cout << "I have created result." << endl;

    return 0;
}

Please tell me how to solve the error of

invalid type argument of unary ‘*’ (have ‘int’)
                         abs = *a;
                                ^

and the error

call of overloaded ‘AbstractValueC(int&)’ is ambiguous
           result.push_back(AbstractValueC(pre));
                                              ^

I actually have a custom type (Abs) in place of int for the abs member in my actual code. Also the requirement is that I cannot call the default constructor of Abs in main. I can use abs = Abs::null;. So please suggest a solution that avoid calling the default constructor for Abs if I replace int with Abs in the class definition.

2 answers

  • answered 2019-05-15 03:13 John3136

    invalid type argument of unary ‘*’ (have ‘int’)

    AbstractValueC(int& a, bool b = false){
                            abs = *a;
                            spec = b;
                    }
    

    Argument a is an int reference, not a pointer, so you can't dereference as *a.

    The code should be abs = a;

    call of overloaded ‘AbstractValueC(int&)’ is ambiguous

    As @strom points out in the comments, you have 2 similar constructors:

    AbstractValueC(int& a, bool b = false)
    AbstractValueC(int a, bool b = false)
    

    Which the compiler cannot readily distinguish between. You should get rid of one of them.

  • answered 2019-05-15 03:28 R.LM

    The real problem is that you are using two constructors with the same signature :

    How does the compiler choose between using :

    AbstractValueC v=AbstractValueC(value);//int constructor
    

    And

    AbstractValueC v=AbstractValueC(value);//reference constructor
    

    When you have

    Int value = 0;//for example
    

    To get rid of this error(ambigueous constructor call) you could either change one of the constructors or replace your reference constructor with a pointer constructor

    To change the constructor to a pointer, you need to create a value pointer in your class and create a contructor:

    // in class declaration
    Int *pointerValue = nullptr;
    
    AbstractValueC(int* pointer, bool b = false);
    
    // implementation
    AbstractValueC::AbstractValueC(Int *pointer, bool b=false) {
        pointerValue=pointer;
    }