2016-07-25 93 views
4

我跟在here的例子,但是我使用模板並調用其中一個派生類的構造函數。下面的代碼工作沒有模板,但包含的時候,我不知道爲什麼我收到以下錯誤:從模板和構造函數的兩個派生類的多繼承

: error: no matching function for call to ‘AbsInit<double>::AbsInit()’ 
    NotAbsTotal(int x) : AbsInit(x) {}; 
           ^

下面是代碼:

#include <iostream> 

using namespace std; 

template<typename T> 
class AbsBase 
{ 
    virtual void init() = 0; 
    virtual void work() = 0; 
}; 

template<typename T> 
class AbsInit : public virtual AbsBase<T> 
{ 
public: 
    int n; 
    AbsInit(int x) 
    { 
     n = x; 
    } 
    void init() { } 
}; 

template<typename T> 
class AbsWork : public virtual AbsBase<T> 
{ 
    void work() { } 
}; 

template<typename T> 
class NotAbsTotal : public AbsInit<T>, public AbsWork<T> 
{ 
public: 
    T y; 
    NotAbsTotal(int x) : AbsInit(x) {}; 
}; // Nothing, both should be defined 


int main() { 
    NotAbsTotal<double> foo(10); 
    cout << foo.n << endl; 

} 
+3

'AbsInit (x)'? –

+0

@TavianBarnes ahaha謝謝!請回答 – pyCthon

+0

這應該工作。但也許我的愚蠢是錯誤的,因爲它應該在GCC 4.5中得到修復,這大大超過了C++ 14。你的編譯器和版本是什麼? –

回答

2

你需要傳遞模板參數(在這種情況下,T)到基地模板級

更改此

template<typename T> 
class NotAbsTotal : public AbsInit<T>, public AbsWork<T> 
{ 
public: 
    T y; 
    NotAbsTotal(int x) : AbsInit<T>(x) // You need to pass the template parameter 
    {}; 
};  
+0

這是令人驚訝的。 'AbsInit'應該是一個可訪問的名稱,指的是'AbsInit '。沒有? –

+0

啊,事實證明,我已經在這之前:http://stackoverflow.com/q/8887864/560648 –

+0

雖然,它應該是固定在GCC 4.5,這大大早於C++ 14 ...嗯... –

2

在下面的代碼片段...

template<typename T> 
class NotAbsTotal : public AbsInit<T> 
{ 
    NotAbsTotal(int x) : AbsInit(x) {} 
}; 

... AbsInit<T>dependent base class

A dependent base class is a base class that is a dependent type and is not the current instantiation.

...這是企圖被稱爲使用不合格injected-class-nameAbsInit),但是:

The injected-class-name of a class (Clause [ class ]) is also considered to be a member of that class for the purposes of name hiding and lookup.

...然而,[temp.dep]/p3

In the definition of a class or class template, the scope of a dependent base class ([temp.dep.type]) is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member. [ Example:

typedef double A; 
template<class T> class B { 
    typedef int A; 
}; 
template<class T> struct X : B<T> { 
    A a;    // a has type double 
}; 

[...]

end example ]

這樣,AbsInit不能結合於存在於的AbsInit<T>本身的範圍注入類名 。這個名字,單獨留存,受unqualified name lookup的約束,並且指向在全局命名空間中找到的類模板。

要避免錯誤或執行所需的名稱解析,模板參數列表追加到類模板名稱AbsInit

NotAbsTotal(int x) : AbsInit<T>(x) {} 
//       ~~^ 

或使用限定名稱:

NotAbsTotal(int x) : NotAbsTotal::AbsInit(x) {} 
//     ~~~~~~~~~~^ 

備註:一旦基類不依賴(即使用具體類型,例如,AbsInit<int>),則可以使用注入類名稱的非限定形式。