2013-10-09 35 views
1

我想要做的是:一個簡單的存儲類,定義爲一個儘可能通用的模板。並且能夠從這個類派生另一個,它可以接受任何東西,將它轉換爲int(算法在這裏不相關),並將其存儲在底層類中。具有不同簽名的多態性和重載函數

但是,這並不像預期的那樣工作。這裏是最小的測試情況下,我寫道:

template<typename T> 
class A { 
    public: 
    void f(T& foo) { } 
}; 

class B : public A<int> { 
    public: 
    template<typename T> 
    void f(T& foo) { } 
}; 

int main() { 
    A<int>* ptr = new B; 
    ptr->f("foo"); 
    delete ptr; 
    return 0; 
} 

當然,這並不工作:

[email protected]:~/Workspace/Test/src$ icpc -o Test Test.cpp 
Test.cpp(16): error: a reference of type "int &" (not const-qualified) cannot 
be initialized with a value of type "const char [4]" 
    ptr->f("foo"); 
     ^

compilation aborted for Test.cpp (code 2) 

有什麼辦法來強制編譯器使用方法定義從B類,或者這是一個真的不好主意?

-

編輯地:繼承公衆。

回答

3

首先,正如@GermanDiago指出的那樣,您使用的是私有繼承,所以您會遇到「基類無法訪問」錯誤。公共地從A<int>更改B

即便如此,這並不能解決問題。名稱查找基於靜態類型。當你有一個指向A<int>的指針時,通過該指針訪問成員將僅查看A<int>的成員。

你必須通過B式訪問,看看B的成員:

int main() { 
    B* ptr = new B; 
    ptr->f("foo"); 
    delete ptr; 
    return 0; 
} 

當然,如果我正確地理解你的問題,這是不是你真正想要的。您可以改爲Curiously Recurring Template Pattern

template <class T, class Derived> 
class A { 
    public: 
    template <class U> 
    void f(U& bar) { 
     static_cast<Derived*>(this)->f(bar); 
    } 

    void f(T& foo) { 

    } 
}; 


class B : public A<int, B> 
{ 
    public: 
    template <class T> 
    void f(T &foo) { 
     //will be called from A's f(U&) 
    } 
}; 


int main() { 
    A<int, B>* ptr = new B; 
    ptr->f("foo"); 
    delete ptr; 
    return 0; 
} 

Live example

當然,這具有成爲BA的類型的一部分下行。在編譯期間,我認爲沒有辦法解決這個問題。

+0

感謝您的幫助解釋。顯然,我不得不多想一想...... – Pierre

1

您必須使用公有繼承:

class B : public A<int> { 
    //... 
} 

是,一個在C++中關係是通過公有繼承。私有繼承是你目前使用的。

+0

是的,但這仍然不允許通過指向'A'的指針調用'B :: f'。 – Angew

+0

謝謝。簡單的錯誤,我剛剛糾正。仍然沒有解決主要問題:/ – Pierre

相關問題