部分排序期间成员函数模板的原始类型是什么
what's the original type for a member function template during partial ordering
考虑这个例子
struct A { };
template<class T> struct B {
template<class R> int operator*(R&); // #1
};
template<class T, class R> int operator*(T&, R&); // #2
偏序将应用于 #1
和 #2
至 select 最佳可行函数模板。
Two sets of types are used to determine the partial ordering. For each of the templates involved there is the original function type and the transformed function type. The deduction process uses the transformed type as the argument template and the original type of the other template as the parameter template. This process is done twice for each type involved in the partial ordering comparison: once using the transformed template-1 as the argument template and template-2 as the parameter template and again using the transformed template-2 as the argument template and template-1 as the parameter template.
Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph)
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template. [ Note: The type replacing the placeholder in the type of the value synthesized for a non-type template parameter is also a unique synthesized type. — end note ] If only one of the function templates M is a non-static member of some class A, M is considered to have a new first parameter inserted in its function parameter list. Given cv as the cv-qualifiers of M (if any), the new parameter is of type “rvalue reference to cv A” if the optional ref-qualifier of M is && or if M has no ref-qualifier and the first parameter of the other template has rvalue reference type. Otherwise, the new parameter is of type “lvalue reference to cv A”.
所以,#2
的原始类型是int operator*(T&, R&)
,转换后的类型是int operator*(UniqueA&, UniqueB&)
,#2
的原始类型是毫无疑问的。但是,我不知道 #1
(member function template).
的原始类型是什么
从该规则的结构来看,上述规则中强调的部分应该被视为生成转换模板的步骤。
那么,#1
的原始类型是int operator*(B<T>&, R&)
还是int operator*(R&)
。如果是后者,那就不符合常识了。由于int operator*(R&)
和int operator*(T&, R&)
参数个数不匹配,如何比较(A对P)?
如何正确阅读变形模板的生成规则?如果强调的部分不认为是转换的一个步骤,而是偏序过程中成员函数的一般规则,该规则是否会误导将这样的规则放在转换过程之后?
是的,有点乱。正如您所观察到的,class 非静态成员函数的“原始类型”缺少插入的 this
参数是没有意义的。
使其工作的唯一方法是第 3 条中的后续段落适用于 [temp.deduct.partial] 另一侧的“原始”函数类型以及“转换后的”函数类型.对于当前第二段的第一句,您可以这样阅读它,将“每个”读作适用于转换后的函数类型和原始函数类型:
Each function template M that is a member function is considered to have a new first parameter of type X(M) [...]
但是,自从 P2108 中对 CWG 2445 的决议以来,我们还有另外一句话:
If exactly one of the function templates was considered [...] via a rewritten candidate with a reversed order of parameters, then the order of the function parameters in its transformed template is reversed.
所以我们很明显地不对称地应用了这种逆转,给出了一个荒谬的结果。从好的方面来说,它应该如何阅读是相当清楚的;对函数类型(this
插入和参数反转)的调整应先于唯一类型 synthesis/substitution 应用,并同样应用于“原始”和转换后的函数类型。
据我所知,这个缺陷似乎没有报告给核心语言工作组;它没有出现在 C++ Standard Core Language Active Issues 列表中。
考虑这个例子
struct A { };
template<class T> struct B {
template<class R> int operator*(R&); // #1
};
template<class T, class R> int operator*(T&, R&); // #2
偏序将应用于 #1
和 #2
至 select 最佳可行函数模板。
Two sets of types are used to determine the partial ordering. For each of the templates involved there is the original function type and the transformed function type. The deduction process uses the transformed type as the argument template and the original type of the other template as the parameter template. This process is done twice for each type involved in the partial ordering comparison: once using the transformed template-1 as the argument template and template-2 as the parameter template and again using the transformed template-2 as the argument template and template-1 as the parameter template.
Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph)
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template. [ Note: The type replacing the placeholder in the type of the value synthesized for a non-type template parameter is also a unique synthesized type. — end note ] If only one of the function templates M is a non-static member of some class A, M is considered to have a new first parameter inserted in its function parameter list. Given cv as the cv-qualifiers of M (if any), the new parameter is of type “rvalue reference to cv A” if the optional ref-qualifier of M is && or if M has no ref-qualifier and the first parameter of the other template has rvalue reference type. Otherwise, the new parameter is of type “lvalue reference to cv A”.
所以,#2
的原始类型是int operator*(T&, R&)
,转换后的类型是int operator*(UniqueA&, UniqueB&)
,#2
的原始类型是毫无疑问的。但是,我不知道 #1
(member function template).
从该规则的结构来看,上述规则中强调的部分应该被视为生成转换模板的步骤。
那么,#1
的原始类型是int operator*(B<T>&, R&)
还是int operator*(R&)
。如果是后者,那就不符合常识了。由于int operator*(R&)
和int operator*(T&, R&)
参数个数不匹配,如何比较(A对P)?
如何正确阅读变形模板的生成规则?如果强调的部分不认为是转换的一个步骤,而是偏序过程中成员函数的一般规则,该规则是否会误导将这样的规则放在转换过程之后?
是的,有点乱。正如您所观察到的,class 非静态成员函数的“原始类型”缺少插入的 this
参数是没有意义的。
使其工作的唯一方法是第 3 条中的后续段落适用于 [temp.deduct.partial] 另一侧的“原始”函数类型以及“转换后的”函数类型.对于当前第二段的第一句,您可以这样阅读它,将“每个”读作适用于转换后的函数类型和原始函数类型:
Each function template M that is a member function is considered to have a new first parameter of type X(M) [...]
但是,自从 P2108 中对 CWG 2445 的决议以来,我们还有另外一句话:
If exactly one of the function templates was considered [...] via a rewritten candidate with a reversed order of parameters, then the order of the function parameters in its transformed template is reversed.
所以我们很明显地不对称地应用了这种逆转,给出了一个荒谬的结果。从好的方面来说,它应该如何阅读是相当清楚的;对函数类型(this
插入和参数反转)的调整应先于唯一类型 synthesis/substitution 应用,并同样应用于“原始”和转换后的函数类型。
据我所知,这个缺陷似乎没有报告给核心语言工作组;它没有出现在 C++ Standard Core Language Active Issues 列表中。