5.13.1.1.2.2.
确定最优
在收集了所有的候选者后,需要挑出可行的候选者(因为收集的时候,我们只考虑了类型,没有别的),并为涉及的转换函数评估等级,以选出最优的候选。下面的代码执行这个处理。
build_user_type_conversion_1 (continue)
2478
candidates = splice_viable
(candidates, pedantic
, &any_viable_p);
2479
if (!any_viable_p)
2480
return
0;
2481
2482
cand = tourney
(candidates);
5.13.1.1.2.2.1.
挑选可行的候选者
在下面的函数中,其参数
strict_p
被传递入
pedantic
的值,它如果非
0
,就要求编译器对标准所禁止的一切给出警告。回忆如果隐式转换不能奏效,
implicit_conversion
将返回
NULL
;而对于标准所禁止的转换,将设置
ICS_BAD_FLAG
标记。
2165
static
struct
z_candidate
*
2166
splice_viable
(struct
z_candidate *cands,
in
call.c
2167
bool strict_p,
2168
bool
*any_viable_p)
2169
{
2170
struct
z_candidate *viable;
2171
struct
z_candidate **last_viable;
2172
struct
z_candidate **cand;
2173
2174
viable = NULL;
2175
last_viable = &viable;
2176
*any_viable_p = false;
2177
2178
cand = &cands;
2179
while
(*cand)
2180
{
2181
struct
z_candidate *c = *cand;
2182
if (strict_p ?
c->viable == 1 : c->viable)
2183
{
2184
*last_viable = c;
2185
*cand = c->next;
2186
c
->next
= NULL;
2187
last_viable =
&c->next;
2188
*any_viable_p = true;
2189
}
2190
else
2191
cand = &c->next;
2192
}
2193
2194
return
viable ? viable : cands;
2195
}
5.13.1.1.2.2.2.
选出最优
【
3
】的条文
13.3.3
.2
“隐式转换序列排名“给出了挑选最优候选者的规则
[over.ics.rank
]
。
而
implicit_conversion
通过,首先尝试标准转换及引用绑定,如果失败,才尝试用户定义转换,实现了规则
2
的第一部分。
1. 2. — — 3. — — S1 — S1 — S1 [ int f(const int f(int *); int i; int j = f(&i); // Calls f(int *) — — S1 int f(const int f(int &); int g(const int g(int); int i; int j = f(i); // Calls f(int &) int k = g(i); // ambiguous class public void f() const void f(); }; void g(const a.f(); //Calls X::f() const b.f(); //Calls X::f() } — — struct operator } a; int f(int); int f(float); int i = f(a); // Calls f(int), because short → int is better than short — 4. — — — struct struct struct C *pc; int f(A *); int f(B *); int i = f(pc); // Calls f(B *) — — — A::* — C — B* — — B::* — B [ |
5936
static
struct
z_candidate
*
5937
tourney
(struct
z_candidate *candidates)
in
call.c
5938
{
5939
struct
z_candidate *champ = candidates, *challenger;
5940
int fate;
5941
int
champ_compared_to_predecessor = 0;
5942
5943
/*
Walk through the list once, comparing each current champ to the next
5944
candidate, knocking out a candidate or two
with each comparison.
*/
5945
5946
for
(challenger = champ->next; challenger; )
5947
{
5948
fate = joust
(champ, challenger, 0);
5949
if (fate == 1)
5950
challenger =
challenger->next;
5951
else
5952
{
5953
if (fate == 0)
5954
{
5955
champ =
challenger->next;
5956
if (champ == 0)
5957
return
0;
5958
champ_compared_to_predecessor = 0;
5959
}
5960
else
5961
{
5962
champ = challenger;
5963
champ_compared_to_predecessor = 1;
5964
}
5965
5966
challenger =
champ->next;
5967
}
5968
}
5969
5970
/*
Make sure the champ is better than all the candidates it hasn't yet
5971
been
compared to.
*/
5972
5973
for
(challenger = candidates;
5974
challenger != champ
5975
&&
!(champ_compared_to_predecessor && challenger->next == champ);
5976
challenger =
challenger->next)
5977
{
5978
fate = joust
(champ, challenger, 0);
5979
if (fate != 1)
5980
return
0;
5981
}
5982
5983
return
champ;
5984
}
通过
joust
候选者被一个个比较来选出最佳者,该函数返回
1
如果
champ
是更优的,
-1
如果
challenger
是更优的,或者
0
如果具有二义性。注意到
champ
总是指向列表中的前一个候选者,而
challenger
是紧跟
champ
之后的候选者。看到在
5946
行的
FOR
循环中
champ
总是指向两个中较佳者,如果能确定的话。
在
5973
行的
FOR
循环中,如果
champ_compared_to_predecessor
为
0
,那么退出的条件变成:“
challenger != champ
”;否则就变成:“
challenger != champ && challenger->next != champ
”。注意到仅当
challenger
最后一次发现优于
champ
(因而
champ
被
challenger
更新),并之后没有出现二义性的结果时,
champ_compared_to_predecessor
可以是
1
;而这个标记
0
,仅当最后一次比较的结果是
champ
优于
chanlleger
。因此对于该标记为
1
,
champ
之前的候选者不需要比较,但当标记为
0
时需要包括之。为什么需要第二个
FOR
循环呢?首先注意到如果找到最佳候选者,最后一次的比较必然不会出现二义性,否则该函数将在
5957
行返回
0
。另外看到如果出现二义性,这两个候选者都被跳过,比较在后面的候选者中重新开始。因此有可能具有二义性的候选者要优于在第一个
FOR
循环中找到的最佳候选者,而这个情形,在第二
FOR
循环中,将被发现为一个错误,并在
5980
行返回
0
。
在上面看到,被选出的可行候选者的
viable
域是非
0
值。并记得如果该转换不为标准所允许,这个域将保存值
-1
。作为一个快速的挑选,不同的
viable
值显示谁为更优。毫无疑问,标准所允许的转换总是更优胜。
5653
static
int
5654
joust
(struct
z_candidate
*cand1, struct
z_candidate *cand2, bool warn)
in call.c
5655
{
5656
int winner = 0;
5657
int i, off1 = 0, off2 = 0,
len;
5658
5659
/* Candidates that involve bad conversions are
always worse than those
5660
that
don't.
*/
5661
if (cand1->viable >
cand2->viable)
5662
return
1;
5663
if (cand1->viable <
cand2->viable)
5664
return
-1;
5665
5666
/*
If we have two pseudo-candidates for conversions to the same type,
5667
or two
candidates for the same function, arbitrarily pick one.
*/
5668
if (cand1->fn ==
cand2->fn
5669
&& (TYPE_P
(cand1->fn) || DECL_P (cand1->fn)))
5670
return
1;
5671
5672
/*
a viable function F1
5673
is
defined to be a better function than another viable function F2 if
5674
for
all arguments i, ICSi(F1) is not a worse conversion sequence than
5675
ICSi(F2), and then */
5676
5677
/*
for some argument j, ICSj(F1) is a better conversion sequence than
5678
ICSj(F2) */
5679
5680
/*
For comparing static and non-static member functions, we ignore
5681
the
implicit object parameter of the non-static function. The
5682
standard says to pretend that the static
function has an object
5683
parm,
but that won't work with operator overloading.
*/
5684
len = TREE_VEC_LENGTH
(cand1->convs);
5685
if (len != TREE_VEC_LENGTH
(cand2->convs))
5686
{
5687
if (DECL_STATIC_FUNCTION_P
(cand1->fn)
5688
&& !
DECL_STATIC_FUNCTION_P (cand2->fn))
5689
off2 = 1;
5690
else if (!
DECL_STATIC_FUNCTION_P (cand1->fn)
5691
&&
DECL_STATIC_FUNCTION_P (cand2->fn))
5692
{
5693
off1 = 1;
5694
--len;
5695
}
5696
else
5697
abort ();
5698
}
5699
5700
for
(i = 0; i < len; ++i)
5701
{
5702
tree t1 = TREE_VEC_ELT
(cand1->convs, i+off1);
5703
tree t2 = TREE_VEC_ELT
(cand2->convs, i+off2);
5704
int comp =
compare_ics
(t1, t2);
5705
5706
if (comp != 0)
5707
{
5708
if (warn_sign_promo
5709
&& ICS_RANK
(t1) + ICS_RANK (t2) == STD_RANK + PROMO_RANK
5710
&& TREE_CODE (t1) ==
STD_CONV
5711
&& TREE_CODE (t2) ==
STD_CONV
5712
&& TREE_CODE
(TREE_TYPE (t1)) == INTEGER_TYPE
5713
&& TREE_CODE
(TREE_TYPE (t2)) == INTEGER_TYPE
5714
&& (TYPE_PRECISION
(TREE_TYPE (t1))
5715
== TYPE_PRECISION
(TREE_TYPE (t2)))
5716
&& (TREE_UNSIGNED
(TREE_TYPE (TREE_OPERAND (t1, 0)))
5717
|| (TREE_CODE
(TREE_TYPE (TREE_OPERAND (t1, 0)))
5718
==
ENUMERAL_TYPE)))
5719
{
5720
tree type = TREE_TYPE
(TREE_OPERAND (t1, 0));
5721
tree type1, type2;
5722
struct
z_candidate *w, *l;
5723
if (comp > 0)
5724
type1 = TREE_TYPE
(t1), type2 = TREE_TYPE (t2),
5725
w = cand1, l =
cand2;
5726
else
5727
type1 = TREE_TYPE
(t2), type2 = TREE_TYPE (t1),
5728
w = cand2, l = cand1;
5729
5730
if (warn)
5731
{
5732
warning
("passing `%T' chooses `%T' over `%T'",
5733
type,
type1, type2);
5734
warning ("
in call to `%D'", w->fn);
5735
}
5736
else
5737
add_warning (w, l);
5738
}
5739
5740
if (winner &&
comp != winner)
5741
{
5742
winner = 0;
5743
goto
tweak;
5744
}
5745
winner = comp;
5746