94060


部分特殊化のマッチングはどのように行われているのでしょうか？  
例えば次のコードが何故コンパイルできないのかわかりません。

[code]

    $ clang -v
    clang version 9.0.0-2~ubuntu18.04.2 (tags/RELEASE_900/final)
    Target: x86_64-pc-linux-gnu
    
[/code]

[code]

    template <bool, typename T>
    struct hoge {};
    
    template <bool, typename T>
    struct hoge<true, T>
    {};
    
    int main()
    {
        hoge<true, int> h;
        (void)h;
    }
    
[/code]

[code]

    error: class template partial specialization contains a template parameter that cannot be deduced;
        this partial specialization will never be used
    
[/code]

マッチすることがないという旨のエラーのようです。  
↓のようにすればコンパイルはできるのですが、↑のコードでも上手くいきそうな気がしてしまいます。

[code]

    template <bool, typename T>
    struct hoge {};
    
    template <typename T>
    struct hoge<true, T>
    {};
    
    int main()
    {
        hoge<true, int> h;
        (void)h;
    }
    
[/code]

C++11のドラフトには次のようにありましたが、関数テンプレートの実引数推定と同様の方法で決定されるのでしょうか？  
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf>

> 14.5.5.1 Matching of class template partial specializations  
>  When a class template is used in a context that requires an instantiation
> of the class, it is necessary to determine whether the instantiation is to
> be generated using the primary template or one of the partial
> specializations. **This is done by matching the template arguments of the
> class template specialization with the template argument lists of the
> partial specializations.**  
>  
>  — If exactly one matching specialization is found, the instantiation is
> generated from that specialization.  
>  — If more than one matching specialization is found, the partial order
> rules (14.5.5.2) are used to determine whether one of the specializations is
> more specialized than the others. If none of the specializations is more
> specialized than all of the other matching specializations, then the use of
> the class template is ambiguous and the program is ill-formed.  
>  — If no matches are found, the instantiation is generated from the primary
> template.  
>  
>  **A partial specialization matches a given actual template argument list if
> the template arguments of the partial specialization can be deduced from the
> actual template argument list (14.8.2).**

その場合、どうやってクラステンプレートを関数テンプレートと同様に評価するのか、上記コードの例の`部分特殊化のテンプレート実引数true`はどのような扱いになるのかなど、具体的な定義はどこかに書いてあるのでしょうか？

> 14.5.5.2 Partial ordering of class template specializations

のexampleでは、

[code]

    template<int I, int J> void f(X<I, J, int>); // A
    template<int I> void f(X<I, I, int>); // B
    
[/code]

のように、クラスを引数に取る関数を仮定していましたが、これは順位付けをするための方法として記載されているようで、マッチングにもこれが適用されるのか判断がつきませんでした。

また、仮にこの方法で評価する場合でも、次のコードはコンパイルできてしまいました。（このコードが仕様の解釈として正しいか分かりませんが）

[code]

    template <bool, typename T>
    class X {};
    
    template <bool, typename T>
    void f(X<true, T>) {};
    
    int main()
    {
        X<true, int> x;
        f<true, int>(x);
    }
    
[/code]

よろしくお願いします。


CC BY-SA 4.0
2023-03-02T18:01:44.693
94057
2023-03-03T05:09:05.677
2023-03-02T18:18:01.210
44647
44647
question
c++
クラステンプレートの部分特殊化のマッチングの仕組みについて


<https://timsong-cpp.github.io/cppwp/n3337/temp.class.spec.match#1>

> This is done by matching the template arguments of the class template
> specialization with the template argument lists of the partial
> specializations.

> (クラステンプレートの特殊化のテンプレート引数を部分特殊化のテンプレート引数リストと照合することによって行われます。)

<https://timsong-cpp.github.io/cppwp/n3337/temp.class.spec.match#4>

> In a type name that refers to a class template specialization, (e.g., A<int,
> int, 1>) the argument list shall match the template parameter list of the
> primary template. The template arguments of a specialization are deduced
> from the arguments of the primary template.

> (クラステンプレートの特殊化を参照する型名 (たとえば、 `A<int, int, 1>` )
> では引数リストはプライマリテンプレートのテンプレートパラメーターリストと一致する必要があります。
> 特殊化のテンプレート引数はプライマリテンプレートの引数から推定されます。)

つまり質問の例で言えば `hoge<true, int> h;` の宣言のときにはまずプライマリテンプレートが受け取ってから、 `<true, int>`
にあてはまる部分特殊化である `hoge<true, T>` が発見されて、この部分特殊化のテンプレート引数 `<bool, typename T>`
の実際の内容を推定しようとします。

部分特殊化のテンプレート引数は `hoge<true, T>` のほうを元にして推論が試みられるので `hoge<true, T>`
で使っていないテンプレート引数は推論のしようがないです。


CC BY-SA 4.0
2023-03-03T05:09:05.677
94060
2023-03-03T05:09:05.677
3364
94057
answer