2

When defining a constructor overload whose only purpose is to dereference a value I get an error that I'd like to understand.

Here's the code:

struct _tv {
    string t;
    void* v;
    _tv(string _t, void* _v) {
        t = _t;
        v = _v;
    };
    _tv(_tv* v) { _tv(*v); }; // A
};

And it fails to compile because of:

error: redefinition of 'v'
  _tv(_tv* v) { _tv(*v); };

What I want to do is to be able to construct _tv's like this:

// Suppose 'a' is a valid _tv*
_tv* b = new _tv(a); // B

If I drop that line (A) from my code, it compiles and I could achieve the same result with:

_tv* b = new _tv(*a);

But I don't want that, I want to understand why it doesn't work and why the error states that I'm trying to redefine the argument 'v'.

Ale Morales
  • 2,728
  • 4
  • 29
  • 42

2 Answers2

4
_tv(*v);

Declares a variable of type "pointer to _tv". The name of that variable is v.

Consider [dcl.meaning]/6:

In a declaration T D where D has the form

      ( D1 )

the type of the contained declarator-id is the same as that of the contained declarator-id in the declaration

  T D1

Parentheses do not alter the type of the embedded declarator-id, but they can alter the binding of complex declarators.

It seems you want to use delegating constructors:

_tv(_tv* v) : _tv(*v) {}

And define an appropriate copy constructor (if necessary).

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • Mmm, ok, so how should I declare the constructor in order to achieve the desired behavior? (Line marked w/ B) – Ale Morales Nov 26 '14 at 00:01
  • You can use a copy constructor `_tv(_tv const& v)` and not use the constructor you have. – R Sahu Nov 26 '14 at 00:04
  • @almosnow You mean define? But what exactly do you want to achieve? – Columbo Nov 26 '14 at 00:05
  • The delegated constructor solved it. I wanted to create copies of a _tv* directly without derefencing on the new() call. Apparently it works now, thanks a lot!. And now I'll dive into how delegate contructors work... – Ale Morales Nov 26 '14 at 00:09
1
struct _tv {
    string t;
    void* v;
    _tv(string _t, void* _v) {
        t = _t;
        v = _v;
    }
    _tv(_tv* ptr) {
        t = ptr->t;
        v = ptr->v;
    } // A
};

What you'r trying to do is constructor delegration, algo need the pointer called ptr to not shadow v https://en.wikipedia.org/wiki/C++11#Object_construction_improvement

also leading underscore names are reserved What are the rules about using an underscore in a C++ identifier?

Community
  • 1
  • 1
destroyer
  • 11
  • 1