Boost logo

Boost :

From: Christopher Woods (cwoods_eol_at_[hidden])
Date: 2007-05-30 11:13:20


Costin Calisov wrote:
>
> I was hopping also, but I must do something wrong, I copy paste your code in
> VC71, and VC8 and get the same error with no copy constructor ...following
> is the full code I used:

No - you didn't do anything wrong. Sorry for the bump steer there. I
thought that I had it working correctly but I jumped the gun apparently
on 2 different things...

The only thing that I can think of is that because of the virtual
keyword MS is assuming that there is multiple inheritance going on and
therefore opting to not attempt to provide a default copy constructor -
as what is the correct copy path for A's values in the classic diamond
inheritance example?

                   class A
  class B : virtual A [class C : virtual A]
                class D : B[, C]

I'm guessing that GCC on the other hand is able to realize that this is
still in fact a single inheritance case that you are attempting to
implement (virtual not withstanding) and can therefore correctly imply
the copy constructor.

                   class A
  class B : virtual A
                 class D : B

So let's try a modified round #1 approach for MSVC:

class final_base
{
protected:
    final_base() {}
};

class final : public virtual final_base
{
protected:
    final() {}
};

class B : final
{
public:
    B() {}
    B(const B&)
    {
        /*
           MS Compiler requires we provide copy constructor
           when virtual is used in the inheritance chain.
        */
    }
};

class C : B
{
public:
    C() {} // Error: Can't derive but unclear error msg IMHO
};

int main()
{
    B t1;
    B t2(t1);
}

Alternative (round #2) - if you don't want to have to specify a copy
constructor then you'll have to make a tradeoff in the class declaration:

class final2
{
protected:
    final2() {}
};

class D : virtual final2
/* Not as clean IMHO as you must remember to use 'virtual' or all is lost */
{
public:
    D() {}
};

class E : D
{
public:
    E() {} // Error: Can't derive but msg unclear IMHO
};

int main()
{
    D t1;
    D t2(t1);
}

Personally, I think I'd rather go with the modified round #1 approach
and write a copy constructor for B. The round 2 approach requires that
a class writer remember to use 'virtual final' because if they just used
'final' then you can still derive from it.

Assuming that you agree with that assessment, then it becomes necessary
for you to find a way to make GCC also baulk unless a copy constructor
is provided with the B class (assuming you want some portability).
Unfortunately I don't have GCC on my machines so I can't help you there
- a protected or private copy constructor within final or final_base
might make GCC complain... You'll have to experiment.

HTH,

-Chris


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk