30

次の関数テンプレートの2番目の角かっこ<>の理由は何ですか。

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

これはSOの質問で出てきて、後に角かっこが欠落していることが示唆されましたがoperator()、説明が見つかりませんでした。

それがフォームのタイプスペシャライゼーション(完全スペシャライゼーション)である場合の意味を理解しています。

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

これはこのシナリオのどこに当てはまりますか?:

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

動作しているように見え、警告/エラーを表示しないサンプルコード(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)
4

1 に答える 1

31

調べてみたところ、14.5.2/2で指定されていることがわかりました。

ローカルクラスにはメンバーテンプレートを含めないでください。アクセス制御規則(11節)は、メンバーのテンプレート名に適用されます。デストラクタはメンバーテンプレートであってはなりません。指定された名前とタイプの通常の(非テンプレート)メンバー関数と、同じタイプの特殊化を生成するために使用できる同じ名前のメンバー関数テンプレートは、両方ともクラスで宣言できます。両方が存在する場合、明示的なテンプレート引数リストが指定されていない限り、その名前とタイプの使用は非テンプレートメンバーを参照します。

そしてそれは例を提供します:

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
}

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

結論:GCCはそれを間違えています。私もコードをテストしたComeauは、それを正しく理解し、診断を発行します。

"ComeauTest.c"、16行目:エラー:"void doh::operator()(bool)"明示的に特殊化できるエンティティではありません template<> void doh::operator()(bool i)

同じ名前型を参照していないintため、(のみ)のテンプレートの特殊化について不平を言っていないことに注意してください。特殊化が持つ関数型は、であり、これはの関数型とは異なります。非テンプレートメンバー関数、つまり。boolvoid(int)void(bool)

于 2009-06-02T03:06:24.993 に答える