2013-11-24 227 views
5

這是我的第一個問題,我希望我做的一切都是正確的。C++無法從派生類中調用基類方法

我嘗試從boost元組中派生一個類。 Boost的元組提供了一個get()模板方法來訪問各個字段。有趣的是,我不能使用派生類中的方法。

下面的代碼顯示問題:

#include <iostream> 
#include <boost/tuple/tuple.hpp> 
using namespace std; 

template<typename A> 
class Derived : public boost::tuple<A> 
{ 
public: 
    Derived() : boost::tuple<A>() {} 

    A& getVal0() 
    { 
     return get<0>(); 
     // does not compile: 
     //error: 'get' was not declared in this scope 

     return boost::tuple<A>::get<0>(); 
     // does not compile 
     //error: expected primary-expression before ')' token 

     return boost::tuples::get<0>(*this); 
     //works 
    } 
}; 

int main() { 
    Derived<int> a; 

    a.get<0>() = 5; 

    cout << a.get<0>() << endl; 
    cout << a.getVal0() << endl; 
    return 0; 
} 

我不知道爲什麼我可以從主功能

a.get<0>() = 5; 

但不能從A& getVal0()方法中訪問get<0>()方法:

error: 'get' was not declared in this scope 

第二個迴歸線是我的嘗試sc OPE方法調用基類:

return boost::tuple<A>::get<0>(); 

這產生不同的錯誤

error: expected primary-expression before ')' token 

調用外部函數'的boost ::元組::獲得< 0>(*此)的作品。這個解決方法對我來說沒問題。但我仍然想知道爲什麼我現在不能使用元組方法。

在升壓文件是Visual C++

提示的通知! MS Visual C++編譯器不支持成員獲取函數。此外,編譯器在找到非成員get函數時沒有明確的命名空間限定符。因此,在編寫應使用MSVC++ 6.0進行編譯的代碼時,所有獲取調用應該被限定爲:tuples :: get(a_tuple)。

但是我使用GCC 4.5.2 & 4.8.1

在此先感謝

+5

+1我必須這樣說:除了標的物之外,您的問題應作爲本網站上發佈的任何新用戶的示例。 (1)你認爲你有的問題,(2)展示這個問題的示例代碼,(3)試圖解決問題,(4)每個人的每個結果嘗試,(5)你使用的工具,包括版本信息,以及(6)研究你認爲根本問題可能是什麼。對於一般的職位來說,這很棒;對於一個*第一*郵政來說,它非常出色,很少見到這種交付。 – WhozCraig

+0

WhozCraig這是非常好的,你可以給一個初學者這麼多好話和積極的建議 – 4pie0

+0

@piotruś當這樣的問題發佈時不難。我很死 - 認真對待這個模範。我只希望OP知道如何標記解決方案,因爲我非常確定Dietmar有這個解決方案。 = P – WhozCraig

回答

3

假設有在基類中的成員get<I>()函數模板,你可能想使用

this->template get<0>() 

this部分是需要使它成爲一個依賴查找(你也可以使用適當的類的資格,但這有點痛苦和不必要的除非你隱藏了一個基類的名字)。 template部分有必要告訴編譯器,從屬名稱(get)碰巧是一個模板。

爲什麼需要this(或其他一些資質)和template的主要原因是對模板的兩相編譯模型:

  • 不立即依賴於一個模板參數某種形式的任何名稱只在階段I期間查看,即在模板被定義的上下文中。由於模板參數未知,因此基類的確切佈局未知(可能是專用的),因此基類中的任何名稱都將被忽略。使用任何使名稱取決於模板參數的限定,例如使用this->將查找移動到階段II,即,當模板被實例化時。
  • 一旦一個名字是相關的,如果一個表達式涉及一個<字符,而模板在階段I中被解析,也就是說,當模板參數尚不知道時,就會產生歧義:<既可以是成員函數調用的顯式模板參數,或者它可以是小於運算符。由於模板參數的明確提及很少見(至少,當這些規則制定時很少見),因此默認情況下它被認爲是小於運算符。要聲明該名稱實際上是一個具有明確指定的模板參數的成員函數模板,它需要在關鍵字template之前(非常類似於需要typename的類型)。
+0

最大的問題是爲什麼會發生這種情況。感謝'this-> template'提示我找到了[link](http://stackoverflow.com/questions/5533354/what-does-a-call-to-this-template-snamename-do)。 Stroustrups中$ C.13.6 C++編程語言解釋了這個問題。但我仍然不確定爲什麼這是派生類中需要的。 –

+0

@EvilAzrael:我在答案中加了一些解釋。 –

+0

感謝您的解釋。 :-) –

相關問題