2

私が理解している、非常に貧弱な C++ プログラミング形式であり、おそらく実際には決して使用されるべきではない、エッジ ケース シナリオについてお聞きしたいと思います。ただし、テンプレートの構文を完全に理解していることを確認したいと思います。

私の質問は、単純に、テンプレートの特殊化におけるテンプレート パラメーターの反転に関するものです。私の質問を最も簡潔に示すサンプルコードを次に示します。

#include <iostream>

template<typename T1, typename T2>
class A
{
public:
    int foo()
    {
        return 1;
    }
};

template<typename T1, typename T2>
class A<T2, T1> // <-- Arguments reversed in template specialization
{
public:
    int foo()
    {
        return 2;
    }
};

int main()
{
    A<int, int> a;
    std::cout << a.foo(); // Output is "2"; the specialized version is called.
    return 0;
}

前述のように、このプログラムを実行すると、出力は "2" になります。テンプレート クラスの特殊化されたバージョンが、テンプレート コンパイラによってインスタンス化されます。

これについて考えると、どのような状況でも、テンプレート クラスの特殊化バージョンがテンプレート コンパイラによってインスタンス化されるコードを記述することは不可能であると私は信じています。A<first_type, second_type>テンプレート コンパイラは最初に一致する特殊化を検索し、2 つの引数の特殊化は、型をインスタンス化するすべてのクライアント コード(特に、特殊化されたテンプレートの定義内の構文でfirst_type対応するもの)に常に一致するため、したがって、特殊化されていないバージョンには、どのような状況でも到達できないというのは本当のようです。T2template<typename T1, typename T2>

私は正しいですか?そうでない場合、誰かがテンプレート クラス A を使用し、特殊化されていないバージョンのテンプレートをインスタンス化できるクライアント コードを示してもらえますか?

4

1 に答える 1

4

私はあなたが正しいと思います。プライマリ テンプレートにアクセスできません。部分的な特殊化が定義される前にそれをインスタンス化しようとすると、プログラムの形式が正しくなくなります。診断は必要ありません。

最近、部分的な特殊化が (部分的な順序付け規則によって) プライマリ テンプレートよりも特殊化されていない場合、その部分的な特殊化を不適切な形式としてマークすることについての考えがありました。あなたのコードが害を及ぼすことはありませんが、人々は、部分的な特殊化が主要なテンプレートよりも特殊化されていない別のテストケースを考え出しました:

template <int B, typename Type1, typename... Types>
struct A;

template<typename... Types>
struct A<0, Types...> { };

最初のパラメーターの場合、プライマリ テンプレートはあまり特化されていませんが、次のパラメーターの場合、プライマリ テンプレートはより特化されており、その逆も同様です。部分的な特殊化の最初のパラメーターを特殊化せずに変数のままにしておくことで、部分的な特殊化をプライマリ テンプレートよりも特殊化することさえできます。これはちょっと奇妙で、部分的な特殊化の目的ではありません。

于 2012-06-17T13:33:31.897 に答える