C 言語では関数テンプレートの部分特殊化が禁止されているのはなぜですか?プライマリ テンプレートと特定の特殊化は許可されますが、テンプレート パラメーター内の型を部分的に制限する部分的特殊化は許可されません。
C 言語仕様では、部分的特殊化は不必要であると考えられているため、明示的に禁止されています。部分特殊化によって実現される機能は、クラスまたは名前空間内で個々の関数インスタンスを囲む、条件付きコード ブロックを使用してテンプレートを選択的にインスタンス化するなどの代替方法を使用して複製できます。
部分特殊化が使用されていない次の例を考えてみましょう。 allowed:
template<typename T, typename U> void f() {} //allowed! template<> void f<int, char>() {} //allowed! template<typename T> void f<char, T>() {} //not allowed! template<typename T> void f<T, int>() {} //not allowed!
この動作は直感に反するように見えるかもしれませんが、理論的根拠は明らかです。部分的な特殊化では、テンプレートのインスタンス化中にあいまいさが生じ、意図しない動作が発生する可能性があります。この言語は、プライマリ テンプレートと特定の特殊化を厳密に分離することにより、予測可能で明確に定義されたテンプレートのインスタンス化を保証します。
ただし、これは部分的な特殊化がまったく役に立たないという意味ではありません。この関数をクラスまたは名前空間に組み込むことで、同様の効果を効果的に達成できます。
#include <iostream> using namespace std; void say(const char s[]) { std::cout << s << std::endl; } namespace detail { template< class T, class U > struct F { static void impl() { say("1. primary template"); } }; template<> struct F<int, char> { static void impl() { say("2. <int, char> explicit specialization"); } }; template< class T > struct F< char, T > { static void impl() { say("3. <char, T> partial specialization"); } }; template< class T > struct F< T, int > { static void impl() { say("4. <T, int> partial specialization"); } }; } // namespace detail template< class T, class U > void f() { detail::F<T, U>::impl(); } int main() { f<char const*, double>(); // 1 f<int, char>(); // 2 f<char, double>(); // 3 f<double, int>(); // 4 }
このコードは、クラス メンバーを使用して部分特殊化をエミュレートする方法を示しています。関数のそれぞれの特定のインスタンス化は、独自の静的メンバー関数内に囲まれており、言語の制限に違反することなく、同様のレベルの特殊化を提供します。これらの回避策を採用することで、確立された言語規則を遵守しながら、部分特殊化の目的の機能を効果的に実現できます。
以上がC では関数テンプレートの部分特殊化が禁止されているのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。