6

テンプレートと部分的な特化で遊んでいますが、書き方がわからない特化が 1 つあります... 読みやすくするためにコードを単純化します。

考えてみよう

template <typename T>
    class x
{
    ...
};

通常、私は次のように専門化できます。

class x<a_type>
{
    ...
};

テンプレート タイプでも機能します。

template <typename T>
    class x<std::vector<T>>
{
    ...
}

ここで、テンプレート化されたクラスにネストされた型の特殊化を行いたいと思います:

template <typename T>
    class y
{
    struct nested_type
    {
        y a_member;
    };

    ...
};

// Here comes the specialization

template <typename T>
    class x<y<T>::nested_type>
{
    ...
};

これは失敗します。y::nested_type の前に 'typename' を入れようとしましたが、問題は解決しませんでした。コンパイラ エラーは次のとおりです。

type/value mismatch at argument 1 in template parameter list for ‘template <class T> struct x’

私がやりたいことは論理的に思えますが、それが可能かどうかはわかりません。g++-4.5 で C++0x を使用しています。そのような特殊化を書くための正しい構文を知っている人はいますか?

4

2 に答える 2

5

答えは、あなたはできないということですこの専門を行います。これは構文エラーではなく、単に実現できないものです。関数のオーバーロードに少し似たテンプレートの特殊化を確認する必要があります。コンパイラは、使用場所で型引数を取得し、利用可能な特殊化を調べ、一致を見つけて、最適なもの (最も特殊化されたもの) を選択する必要があります。あなたの例の問題は、そのような特殊化では「一致を見つける」ステップを実現できないことです。コンパイラは、「nested_type」が一意の型であるとは限りません (例のように)、たとえば、ネストされた typedef である可能性もあります。さらに、コンパイラは、テンプレート "y" のすべての特殊化を既に見ていると予測できないため、nested_type が y (一般的なテンプレート) にネストされた一意の型であっても、

関数のオーバーロードとそこで使用されるマッチング アルゴリズムと同様に、コンパイラは型を推測する機能に制限があり、どの程度の仮定を行うことができるかによって制限されます。x<int>and later useの特殊化がある場合x<int>、一致は自明であり、演繹も仮定も必要ありません。のような特殊化がx<T*>あり、後で使用するx<int*>場合、一致は簡単で、T は であると推測できますint。みたいな専門分野があればx< y<T>::type >次に、任意のバージョンの x を使用すると、コンパイラはどのようにして y::type から T を推定することになっているのでしょうか? 一致するネストされた型になるものがあるかどうかを確認するには、世界全体に存在するすべての可能な型の T を置き換える必要があります。これは不当な期待であり、C++ テンプレートの型推定機能がここで停止する理由です。多くの場合、コンパイラが何かを解決できると期待すべきかどうかを知るには、コンパイラの立場に立って、それが少しでも可能かどうかを確認してください (答えは通常明らかです)。

于 2011-05-24T17:35:22.613 に答える