Understanding How Class Template Partial Specialization Matching Works

Asked 1 years ago, Updated 1 years ago, 297 views

How do you match partial specialization?
For example, I do not know why the following code cannot be compiled:

$clang-v
clang version 9.0.0-2 to ubuntu 18.04.2 (tags/RELEASE_900/final)
Target: x86_64-pc-linux-gnu
template<bool, typename T>
structure hoge {};

template<bool, typename T>
structure hoge<true,T>
{};

int main()
{
    hoge<true,int>h;
    (void)h;
}
 error:class template partial specialization contains a template parameter that cannot be done;
    This partial specialization will never be used

It seems to be an error that does not match.
I can compile like ↓, but I feel that the code of ↑ will work.

template<bool, typename T>
structure hoge {};

template<typename T>
structure hoge<true,T>
{};

int main()
{
    hoge<true,int>h;
    (void)h;
}

The draft of C++11 was as follows, but is it determined in the same way as estimating real arguments in a function template?
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 installation 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 installation is generated from the primary template.

Apartial specialization matches a given actual template argument list if the template arguments of the partial specialization can be reduced from the actual template argument list (14.8.2).

If so, where are the specific definitions written, such as how to evaluate a class template like a function template, and how to handle the partial specialization template real argument true in the example code above?

14.5.5.2 Partial ordering of class template specializations

In the example in ,

template<int I,int J>voidf(X<I,J,int>);//A
template<int I>voidf(X<I,I,int>);//B

As shown in , we assumed a function that takes a class as an argument, but this seemed to be described as a way of ranking, and we could not determine if this would apply to matching.

Also, even if you evaluate it this way, the following code has been compiled (although I don't know if this code is the correct interpretation of the specification).

template<bool, typename T>
class X { };

template<bool, typename T>
voidf(X<true,T>){};

int main()
{
    X<true,int>x;
    f<true, int>(x);
}

Thank you for your cooperation.

c++

2023-03-02 22:43

1 Answers

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.

(This is done by matching the template arguments for class template specialization against the list of template arguments for partial specialization.)

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

In a type name that references 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 from the arguments of the primary.

(For type names that reference class template specialization (for example, A<int,int,1>), the argument list must match the template parameter list in the primary template. Specification template arguments are estimated from the arguments in the primary template.)

In other words, in the example of the question, when hoge<true,int>h; declaration, the primary template is received first, and then hoge<true,T> is discovered, and the actual template content of this partial specialization is

The template argument for partial specialization is based on hoge<true,T>, so it is hard to infer template arguments that hoge<true,T> does not use.


2023-03-03 10:01

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.