関数テンプレートの特殊フォーマット
-
06-09-2019 - |
質問
次の関数テンプレートにおける第二ブラケット<>理由は何ですか
template<> void doh::operator()<>(int i)
このは、それがあることが示唆された場所の質問href="https://stackoverflow.com/questions/937107/do-template-specializations-require-template-syntax"> 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
このscenarionにこのフィットを行いどこ?
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)
解決
私はそれを見て、それは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は、それが間違って取得します。私はまた、コードをテストしているとコモーは、右のそれを取得し、診断を発行します:
それは、同じ名前を参照していないので、
"ComeauTest.c"
、16行目:エラー:"void doh::operator()(bool)"
はその実体ではありません 明示的に特化することができますtemplate<> void doh::operator()(bool i)
、それは(のみint
用)bool
のテンプレートの専門文句を言っていないことに注意してください。とのタイプ:専門のだろうと関数型有するvoid(int)
非テンプレートメンバ関数の関数型は区別されるvoid(bool)
、です。