2012-10-23 90 views
2

我有以下幾點:奇怪的循環模板patterm:雙遺產

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

我希望得到來自OneBaseH<Two>Two,因爲TwoOne專業化和operator~BaseH必須始終返回調用它的對象的類型的引用。

編譯錯誤是明顯的:

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 

如何使_name和兩個OneTwoname訪問,同時設定通過構造代表團const參考?最乾淨的方法是什麼?

+0

我懷疑,如果這是真的[CRTP(http://en.wikipedia.org/wiki/ Curiously_recurring_template_pattern)。或者至少有'虛擬'功能,你沒有利用它。 – iammilind

+0

@iammilind:不確定你的意思,但是對於它的價值,這當然是「真實」代碼的一小部分摘錄 –

+1

當你想消除由於虛擬功能引起的開銷時,CRTP通常很有用(請參閱維基鏈接)。在代碼示例中,它沒有利用它。可能是你發佈的是另一種形式的CRTP。 – iammilind

回答