2

I have the following:

class Base
{
protected:
    std::string _name;

public:
    virtual ~Base(){}

    const std::string &name;

    Base()
        : _name ("(no name)")
        , name(_name)
    {}
};

template <typename T>
class BaseH : public Base
{
public:
    virtual ~BaseH() {}
    BaseH() : Base() {}

    T& operator~(){ ; return static_cast<T&>(*this);}
};

class One : public BaseH<One>
{
public:
    One() : BaseH<One>() { _name = "One"; }

};

class Two
    : public One
    , public BaseH<Two>
{
public:
    Two() : BaseH<Two>() { _name = "Two"; }

};


int main(int argc, char *argv[])
{
    std::cout << Two().name << std::endl;

    return 0;
}

I want to derive Two from both One and BaseH<Two>, because Two is a specialization of One, and the operator~ in BaseH must always return a reference of the type of the object that's calling it.

Compilation errors are obviously:

In constructor ‘Two::Two()’:
  error: reference to ‘_name’ is ambiguous
  error: candidates are: std::string Base::_name
  error:                 std::string Base::_name
In function ‘int main(int, char**)’:
  error: request for member ‘name’ is ambiguous
  error: candidates are: const string& Base::name
  error:                 const string& Base::name

How do I make _name and name accessible in both One and Two, while setting the const references via constructor delegation? What is the cleanest way to do that?

4

1 に答える 1

3

ダイヤモンドの問題を抱えているようです。仮想継承を試しましたか?

例えば:

template <typename T>
class BaseH : virtual public Base
{
    // ...
};

class One : virtual public BaseH<One>
{
    // ...
};

編集: ここでダイヤモンドの問題についてさらに読む: http://www.cprogramming.com/tutorial/virtual_inheritance.html

于 2012-10-23T13:23:35.207 に答える