2017-02-09 62 views
3

標題很拗口,但基本上我寫的是這樣的:我如何在聲明之外爲非專業化的非模板類定義方法?

enum EnumType{ValA, ValB}; 

template<EnumType> class A {}; 

template<> 
class A<ValA> 
{ 
private: 
    double param; 
public: 
    A(double param); 
}; 

template<> 
A<ValA>::A(double param) 
{ 
    // Do Stuff 
} 

,當我嘗試編譯它,我得到:

error: template-id 'A<>' for 'A<(EnumType)0u>::A(double)' does not match any template declaration

我這樣做不對嗎?

類似案件在網上搜索後,我試圖刪除template<>(即使我不明白爲什麼這會工作),但後來我得到

multiple definition of 'A<(EnumType)0u>::A(double)'

我想,我可以代替inlinetemplate<> (我試過並編譯過),但是這並不覺得它是正確的(或者如果是這樣,我不明白爲什麼)。

有人可以向我解釋我寫的是什麼問題,爲什麼改變這似乎工作,以及有什麼正確的方法來做到這一點?

回答

6

Can someone explain to me what is wrong with what I wrote, why changing this seems to work, and what's the proper way to do it ?

的標準說:

Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and not using the template<> syntax.

因此,你的情況,你必須使用:

A<EnumType::ValA>::A(double param) 
{ 
    // Do Stuff 
} 

沒有template<>都只是罰款。這是因爲你實際上專門化了一個明確專門化的類模板的(特殊)成員函數(構造函數)。
請參閱coliru


如果沒有給出明確的專門化,它本來會有所不同。
作爲最小的工作例如:

enum EnumType{ValA, ValB}; 

template<EnumType> class A 
{ 
private: 
    double param; 
public: 
    A(double param); 
}; 

template<> 
A<EnumType::ValA>::A(double) 
{ 
    // Do Stuff 
} 

int main() { 
    A<EnumType::ValA> a{0.}; 
} 

在這種情況下,template<>是因爲你沒有定義已經專門的模板類的成員函數的特化構造函數的定義之前需要。

0

您在類定義的末尾遺漏了分號(;)。 和非模板成員函數可以定義這種方式:

A<ValA>::A(double param) { 
    // Do Stuff 
} 

非正式地,只寫入時所必需的模板的參數列表,例如,用於定義類模板的成員函數模板,這兩個模板參數名單都應該寫

template<class U, class V> 
class A{ 
    template <class T> 
    A(); 
}; 

template<class U, class V> 
template <class T> 
A<U, V>::A() {} 

,並需要對函數模板的顯式特(其中,我想,這就是爲什麼你這樣在這裏使用的原因)一個空的模板參數列表,非正式的,因爲它告訴編譯器這不是一個函數重載。

+0

我想從第二個代碼片段中創建一個類的實例嗎?此外,問題不在於它不是會員模板功能。 – skypjack

+1

感謝您注意到丟失的分號(但這只是我在帖子中輸入的一個錯字,而不是我實際的代碼中的東西) – Eternal

相關問題