2009-06-02 9 views
30

>次の関数テンプレートで:関数テンプレート特殊フォーマット第二ブラケット<理由は何

template<> void doh::operator()<>(int i) 

これは、それが私ができるしかし、operator()後に行方不明括弧があることが示唆されたSO questionに思い付い説明を見つけられません。

それはフォームのタイプ専門(フル分業)だった場合、私は意味を理解する:

関数テンプレートのためしかし
template< typename A > struct AA {}; 
template<> struct AA<int> {};   // hope this is correct, specialize for int 

template< typename A > void f(A); 
template< typename A > void f(A*); // overload of the above for pointers 
template<> void f<int>(int);   // full specialization for int 

がこのscenarionに収まらない場合は?:

template<> void doh::operator()<>(bool b) {} 

動作していると思われるコード例はありませんrnings /エラー(使用のgcc 3.3.3):

#include <iostream> 
using namespace std; 

struct doh 
{ 
    void operator()(bool b) 
    { 
     cout << "operator()(bool b)" << endl; 
    } 

    template< typename T > void operator()(T t) 
    { 
     cout << "template <typename T> void operator()(T t)" << endl; 
    } 
}; 
// note can't specialize inline, have to declare outside of the class body 
template<> void doh::operator()(int i) 
{ 
    cout << "template <> void operator()(int i)" << endl; 
} 
template<> void doh::operator()(bool b) 
{ 
    cout << "template <> void operator()(bool b)" << endl; 
} 

int main() 
{ 
    doh d; 
    int i; 
    bool b; 
    d(b); 
    d(i); 
} 

出力:

operator()(bool b) 
template <> void operator()(int i) 
+0

上記の二重括弧の構文は非常に奇妙です。通常、私は演算子(bool b)を見ましたが、演算子()(bool b)はどのように動作しますか?最初の空()の使用は何ですか? – Jimm

+1

@ Jimmメソッド名は 'operator()'で、1つのパラメータ 'bool b'をとります...これは関数呼び出し演算子です。私のコード例の 'main'を参照してください。' d(b) ' – stefanB

答えて

31

私はそれを見て、それは14.5.2/2で指定されていることを発見しました:

A local class shall not have member templates. Access control rules (clause 11) apply to member template names. A destructor shall not be a member template. A normal (non-template) member function with a given name and type and a member function template of the same name, which could be used to generate a specialization of the same type, can both be declared in a class. When both exist, a use of that name and type refers to the non-template member unless an explicit template argument list is supplied.

そしてそれは、例を提供します。

template <class T> struct A { 
    void f(int); 
    template <class T2> void f(T2); 
}; 

template <> void A<int>::f(int) { } // non-template member 
template <> template <> void A<int>::f<>(int) { } // template member 

int main() 
{ 
    A<char> ac; 
    ac.f(1); //non-template 
    ac.f(’c’); //template 
    ac.f<>(1); //template 
} 

注Sであることspecializationは、明示的な特殊化とインスタンス化を使用して生成された関数を使用して記述する関数を指します。この場合、生成された特殊化と関連があります。 specializationは、テンプレートを明示的に特殊化することで作成した関数を指すだけでなく、よく使用されるテンプレートです。

結論:GCCは間違っています。それはdoesnのため、それは、(のみbool用)intのテンプレートの専門文句を言っていないことを

"ComeauTest.c" , line 16: error: "void doh::operator()(bool)" is not an entity that can be explicitly specialized template<> void doh::operator()(bool i)

注:私は、コードをテストしているとコモーは、右のそれを取得し、診断を発行しますtは同じ名前の型を参照してください。特殊化される関数のタイプはvoid(int)です。これはテンプレート以外のメンバ関数の関数型とは異なり、void(bool)です。

+0

上記の 'テンプレートメンバー'は、「構造体Aの特殊化」のテンプレートメンバーです。今すぐ意味があるので、ac.f()を呼び出すと、パラメータまたは明示的なテンプレートパラメータリスト(正しい名前が何であれ)に基づいて、独自のテンプレート解決が行われます。 – stefanB

+1

ええ、私たちがfに対して明示的に特化したのは、intの構造体Aの特殊化です。一般的な基本テンプレートfは、Aのすべての特殊化のために存在する。だからもちろん、A で呼び出すこともできます(しかし、これはA :: f のためのものなので、私たちの明示的な特殊化は使用しません)。うん、ac.f(stuff)は確かにそれ自身の決議をしています。ここでは、14.8.1/2(「推論可能な後続のテンプレート引数...」)を参照してください。これは役に立ちます: –

+0

ありがとう、研究のためにありがとう:) – stefanB

関連する問題