2017-02-09 2 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

私は、正確に2番目のスニペットからクラスのインスタンスを作成しますか?さらに、問題はメンバテンプレート関数ではないということではありません。 – skypjack

+1

不足しているセミコロンに気づいてくれてありがとう(しかし、それは私が投稿で作ったばかりのもので、実際のコードではうまくいきませんでした) – Eternal

関連する問題