GCC-3.4.6源代码学习笔记(147-续2)

 

unify (continue)

 

9964       case PTRMEM_CST:

9965      {

9966        /* A pointer-to-member constant can be unified only with

9967          another constant.  */

9968        if (TREE_CODE (arg) != PTRMEM_CST)

9969          return 1;

9970

9971        /* Just unify the class member. It would be useless (and possibly

9972          wrong, depending on the strict flags) to unify also

9973          PTRMEM_CST_CLASS, because we want to be sure that both parm and

9974          arg refer to the same variable, even if through different

9975          classes. For instance:

9976

9977           struct A { int x; };

9978           struct B : A { };

9979

9980          Unification of &A::x and &B::x must succeed.  */

9981        return unify (tparms, targs, PTRMEM_CST_MEMBER (parm),

9982                   PTRMEM_CST_MEMBER (arg), strict);

9983      }

9984

9985      case POINTER_TYPE:

9986      {

9987        if (TREE_CODE (arg) != POINTER_TYPE)

9988          return 1;

9989   

9990        /* [temp.deduct.call]

9991

9992          A can be another pointer or pointer to member type that can

9993          be converted to the deduced A via a qualification

9994          conversion (_conv.qual_).

9995

9996          We pass down STRICT here rather than UNIFY_ALLOW_NONE.

9997          This will allow for additional cv-qualification of the

9998          pointed-to types if appropriate.  */

9999   

10000       if (TREE_CODE (TREE_TYPE (arg)) == RECORD_TYPE)

10001         /* The derived-to-base conversion only persists through one

10002           level of pointers.  */

10003         strict |= (strict_in & UNIFY_ALLOW_DERIVED);

10004

10005       return unify (tparms, targs, TREE_TYPE (parm),

10006                  TREE_TYPE (arg), strict);

10007     }

10008

10009     case REFERENCE_TYPE:

10010       if (TREE_CODE (arg) != REFERENCE_TYPE)

10011         return 1;

10012       return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),

10013                  strict & UNIFY_ALLOW_MORE_CV_QUAL);

10014

10015     case ARRAY_TYPE:

10016       if (TREE_CODE (arg) != ARRAY_TYPE)

10017          return 1;

10018       if ((TYPE_DOMAIN (parm) == NULL_TREE)

10019           != (TYPE_DOMAIN (arg) == NULL_TREE))

10020          return 1;

10021       if (TYPE_DOMAIN (parm) != NULL_TREE

10022          && unify (tparms, targs, TYPE_DOMAIN (parm),

10023                   TYPE_DOMAIN (arg), UNIFY_ALLOW_NONE) != 0)

10024          return 1;

10025       return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),

10026                  strict & UNIFY_ALLOW_MORE_CV_QUAL);

10027

10028     case REAL_TYPE:

10029     case COMPLEX_TYPE:

10030     case VECTOR_TYPE:

10031     case INTEGER_TYPE:

10032     case BOOLEAN_TYPE:

10033     case ENUMERAL_TYPE:

10034     case VOID_TYPE:

10035       if (TREE_CODE (arg) != TREE_CODE (parm))

10036         return 1;

10037

10038       if (TREE_CODE (parm) == INTEGER_TYPE

10039          && TREE_CODE (TYPE_MAX_VALUE (parm)) != INTEGER_CST)

10040       {

10041         if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg)

10042            && unify (tparms, targs, TYPE_MIN_VALUE (parm),

10043                     TYPE_MIN_VALUE (arg), UNIFY_ALLOW_INTEGER))

10044           return 1;

10045         if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)

10046            && unify (tparms, targs, TYPE_MAX_VALUE (parm),

10047                     TYPE_MAX_VALUE (arg),

10048                     UNIFY_ALLOW_INTEGER | UNIFY_ALLOW_MAX_CORRECTION))

10049           return 1;

10050        }

10051       /* We have already checked cv-qualification at the top of the

10052         function.  */

10053       else if (!same_type_ignoring_top_level_qualifiers_p (arg, parm))

10054         return 1;

10055

10056       /* As far as unification is concerned, this wins. Later checks

10057         will invalidate it if necessary.  */

10058       return 0;

10059

10060     /* Types INTEGER_CST and MINUS_EXPR can come from array bounds.  */

10061     /* Type INTEGER_CST can come from ordinary constant template args.  */

10062     case INTEGER_CST:

10063       while (TREE_CODE (arg) == NOP_EXPR)

10064         arg = TREE_OPERAND (arg, 0);

10065

10066       if (TREE_CODE (arg) != INTEGER_CST)

10067         return 1;

10068       return !tree_int_cst_equal (parm, arg);

10069

10070     case TREE_VEC:

10071     {

10072       int i;

10073       if (TREE_CODE (arg) != TREE_VEC)

10074         return 1;

10075       if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg))

10076         return 1;

10077       for (i = 0; i < TREE_VEC_LENGTH (parm); ++i)

10078         if (unify (tparms, targs,

10079                 TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i),

10080                 UNIFY_ALLOW_NONE))

10081           return 1;

10082       return 0;

10083     }

 

看一下 9971 行的注释,它解释了为什么推导 PTRMEM_CST_MEMBER ,而不是整个结构。并且注意到对于标量的类型(从 REAL_TYPE ENUMERATE_TYPE ,而 VOID_TYPE 是一个反常,它不能够被用作模板形参,但可以被传递作为缺省实参),它们对应非类型模板形参(不包括 VOID_TYPE )。

 

unify (continue)

 

10085     case RECORD_TYPE:

10086     case UNION_TYPE:

10087       if (TREE_CODE (arg) != TREE_CODE (parm))

10088         return 1;

10089  

10090       if (TYPE_PTRMEMFUNC_P (parm))

10091       {

10092         if (!TYPE_PTRMEMFUNC_P (arg))

10093           return 1;

10094

10095         return unify (tparms, targs,

10096                     TYPE_PTRMEMFUNC_FN_TYPE (parm),

10097                    TYPE_PTRMEMFUNC_FN_TYPE (arg),

10098                    strict);

10099       }

10100

10101       if (CLASSTYPE_TEMPLATE_INFO (parm))

10102       {

10103         tree t = NULL_TREE;

10104

10105         if (strict_in & UNIFY_ALLOW_DERIVED)

10106         {

10107           /* First, we try to unify the PARM and ARG directly.  */

10108           t = try_class_unification (tparms, targs,

10109                                 parm, arg);

10110

10111           if (!t)

10112           {

10113              /* Fallback to the special case allowed in

10114               [temp.deduct.call]:

10115           

10116               If P is a class, and P has the form

10117               template-id, then A can be a derived class of

10118               the deduced A. Likewise, if P is a pointer to

10119               a class of the form template-id, A can be a

10120               pointer to a derived class pointed to by the

10121               deduced A.  */

10122             t = get_template_base (tparms, targs,

10123                                parm, arg);

10124

10125             if (! t || t == error_mark_node)

10126               return 1;

10127           }

10128          }

10129         else if (CLASSTYPE_TEMPLATE_INFO (arg)

10130               && (CLASSTYPE_TI_TEMPLATE (parm)

10131                     == CLASSTYPE_TI_TEMPLATE (arg)))

10132           /* Perhaps PARM is something like S<U> and ARG is S<int>.

10133              Then, we should unify `int' and `U'.  */

10134           t = arg;

10135         else

10136           /* There's no chance of unification succeeding.  */

10137           return 1;

10138

10139         return unify (tparms, targs, CLASSTYPE_TI_ARGS (parm),

10140                    CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE);

10141       }

10142       else if (!same_type_ignoring_top_level_qualifiers_p (parm, arg))

10143         return 1;

10144       return 0;

 

在上面的 10101 行,如果 CLASSTYPE_TEMPLATE_INFO 不是 null ,表示 parm 是一个类模板。看到在该函数的 9741 行, strict_in 拷贝自参数 strict ,其中的 UNIFY_ALLOW_DERIVED 是,当通过函数调用推导模板实参时,在 type_unification_real 中设置的(参考在 maybe_adjust_types_for_deduction 之前的段落)。

 

9486 static tree

9487 try_class_unification (tree tparms, tree targs, tree parm, tree arg)                         in pt.c

9488 {

9489    tree copy_of_targs;

9490

9491    if (!CLASSTYPE_TEMPLATE_INFO (arg)

9492        || (most_general_template (CLASSTYPE_TI_TEMPLATE (arg))

9493          != most_general_template (CLASSTYPE_TI_TEMPLATE (parm))))

9494      return NULL_TREE;

9495

9496     /* We need to make a new template argument vector for the call to

9497      unify. If we used TARGS, we'd clutter it up with the result of

9498      the attempted unification, even if this class didn't work out.

9499      We also don't want to commit ourselves to all the unifications

9500      we've already done, since unification is supposed to be done on

9501      an argument-by-argument basis. In other words, consider the

9502      following pathological case:

9503

9504         template <int I, int J, int K>

9505            struct S {};

9506        

9507         template <int I, int J>

9508            struct S<I, J, 2> : public S<I, I, I>, S<J, J, J> {};

9509        

9510         template <int I, int J, int K>

9511            void f(S<I, J, K>, S<I, I, I>);

9512        

9513         void g() {

9514           S<0, 0, 0> s0;

9515           S<0, 1, 2> s2;

9516        

9517           f (s0, s2);

9518         }

9519

9520      Now, by the time we consider the unification involving `s2', we

9521      already know that we must have `f<0, 0, 0>'. But, even though

9522      `S<0, 1, 2>' is derived from `S<0, 0, 0>', the code is invalid

9523      because there are two ways to unify base classes of S<0, 1, 2>

9524      with S<I, I, I>. If we kept the already deduced knowledge, we

9525      would reject the possibility I=1.  */

9526    copy_of_targs = make_tree_vec (TREE_VEC_LENGTH (targs));

9527   

9528     /* If unification failed, we're done.  */

9529    if (unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm),

9530            CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE))

9531      return NULL_TREE;

9532

9533    return arg;

9534 }

 

这里有一个长的注释解释了为什么使用拷贝的模板实参的 vector ,并给出了一个作为错误的例子。进一步的,如果为在 9517 行的 f 交换 s0 s2 ,这是好的代码。对于形参“ S<I, I, I> ”,“ S<0, 1, 2> ”不是好的结果,因为“ S<0, 1, 2> ”派生自“ S<0, 0, 0> ”及“ S<1, 1, 1> ”,两者都匹配“ S<I, I, I> ”这个形式。回忆【 3 】规定实参推导是以每个实参为单位进行的,在推导之后,所推导的实参应该与之前推导出的结果,或显式给定的实参相匹配。但看到这里对 unify 的调用,只是一个尝试,通过使用模板实参 vector 的拷贝,就可以不改变得到之前推导的实参。

对于上面注释中给出的例子, s2 是不同于 S<I, I, I> 的模板,因此 try_class_unification 9494 行返回,然后进入下面的函数来检查基类是否可以统一(因为现在使用了 UNIFY_ALLOW_DERIVED )。

 

9614 static tree

9615 get_template_base (tree tparms, tree targs, tree parm, tree arg)                             in pt.c

9616 {

9617    tree rval;

9618    tree arg_binfo;

9619

9620    my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)), 92);

9621   

9622    arg_binfo = TYPE_BINFO (complete_type (arg));

9623    rval = get_template_base_recursive (tparms, targs,

9624                                  parm, arg_binfo,

9625                                  NULL_TREE,

9626                                  GTB_IGNORE_TYPE);

9627

9628    /* Since get_template_base_recursive marks the bases classes, we

9629      must unmark them here.  */

9630    dfs_walk (arg_binfo, dfs_unmark, markedp, 0);

9631

9632    return rval;

9633 }

 

这个函数遍历该类的继承树,以前序在基类上执行 try_class_unification 。看到对于 s2 ,其基类“ S<0, 0, 0> ”及“ S<1, 1, 1> ”依次在 9554 行进入 try_class_unification 。但是在最后一次的递归中,分别由 rval r 所指向的,不相等的“ S<0, 0, 0> ”及“ S<1, 1, 1> ”导致该函数在 9566 行返回 error_mark_node

 

9540 static tree

9541 get_template_base_recursive (tree tparms,                                                   in pt.c

9542                          tree targs,

9543                          tree parm,

9544                          tree arg_binfo,

9545                           tree rval,

9546                          int flags)

9547 {

9548    tree binfos;

9549    int i, n_baselinks;

9550    tree arg = BINFO_TYPE (arg_binfo);

9551

9552    if (!(flags & GTB_IGNORE_TYPE))

9553    {

9554      tree r = try_class_unification (tparms, targs,

9555                              parm, arg);

9556

9557      /* If there is more than one satisfactory baseclass, then:

9558

9559        [temp.deduct.call]

9560

9561        If they yield more than one possible deduced A, the type

9562        deduction fails.

9563

9564        applies.  */

9565      if (r && rval && !same_type_p (r, rval))

9566        return error_mark_node;

9567      else if (r)

9568        rval = r;

9569    }

9570

9571    binfos = BINFO_BASETYPES (arg_binfo);

9572    n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;

9573

9574    /* Process base types.  */

9575    for (i = 0; i < n_baselinks; i++)

9576    {

9577      tree base_binfo = TREE_VEC_ELT (binfos, i);

9578      int this_virtual;

9579

9580      /* Skip this base, if we've already seen it.  */

9581      if (BINFO_MARKED (base_binfo))

9582        continue ;

9583

9584      this_virtual =

9585          (flags & GTB_VIA_VIRTUAL) || TREE_VIA_VIRTUAL (base_binfo);

9586       

9587      /* When searching for a non-virtual, we cannot mark virtually

9588        found binfos.  */

9589      if (! this_virtual)

9590        BINFO_MARKED (base_binfo) = 1;

9591       

9592      rval = get_template_base_recursive (tparms, targs,

9593                                   parm,

9594                                   base_binfo,

9595                                   rval,

9596                                   GTB_VIA_VIRTUAL * this_virtual);

9597       

9598      /* If we discovered more than one matching base class, we can

9599        stop now.  */

9600      if (rval == error_mark_node)

9601        return error_mark_node;

9602    }

9603

9604    return rval;

9605 }

 

回到 unify ,如果 10108 行的 try_class_unification ,或 10122 行的 get_template_base ,任一成功,表明推导是可以成功的,那么在 10139 行执行真正的推导。

而在 10142 行,对于普通类,除了最顶层的 cv- 限定词, arg parm 应该是同一个类型。

在下面,如 [temp.deduct.type] 的条款 3 所描述:

“一个函数类型包括该函数每个形参的类型及返回类型。

一个指向成员的指针类型包括所指向类对象的类型,及所指向成员的类型。”

这部分代码相应地处理这些情形。再下面的代码,节点 MINUS_EXPR 可能和 ARRAY_TYPE 一起来,关联的注释给出了一个清楚的解释。

 

unify (continue)

 

10146     case METHOD_TYPE:

10147     case FUNCTION_TYPE:

10148       if (TREE_CODE (arg) != TREE_CODE (parm))

10149         return 1;

10150

10151       if (unify (tparms, targs, TREE_TYPE (parm),

10152               TREE_TYPE (arg), UNIFY_ALLOW_NONE))

10153         return 1;

10154       return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),

10155                               TYPE_ARG_TYPES (arg), 1,

10156                                DEDUCE_EXACT, 0, -1);

10157

10158     case OFFSET_TYPE:

10159       if (TREE_CODE (arg) != OFFSET_TYPE)

10160         return 1;

10161       if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),

10162               TYPE_OFFSET_BASETYPE (arg), UNIFY_ALLOW_NONE))

10163         return 1;

10164       return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),

10165                  strict);

10166

10167     case CONST_DECL:

10168       if (DECL_TEMPLATE_PARM_P (parm))

10169         return unify (tparms, targs, DECL_INITIAL (parm), arg, strict);

10170       if (arg != decl_constant_value (parm))

10171         return 1;

10172       return 0;

10173

10174     case FIELD_DECL:

10175     case TEMPLATE_DECL:

10176       /* Matched cases are handled by the ARG == PARM test above.  */

10177       return 1;

10178

10179     case MINUS_EXPR:

10180       if (tree_int_cst_equal (TREE_OPERAND (parm, 1), integer_one_node)

10181          && (strict_in & UNIFY_ALLOW_MAX_CORRECTION))

10182       {

10183         /* We handle this case specially, since it comes up with

10184           arrays. In particular, something like:

10185

10186             template <int N> void f(int (&x)[N]);

10187

10188           Here, we are trying to unify the range type, which

10189           looks like [0 ... (N - 1)].  */

10190         tree t, t1, t2;

10191         t1 = TREE_OPERAND (parm, 0);

10192         t2 = TREE_OPERAND (parm, 1);

10193

10194         t = fold (build (PLUS_EXPR, integer_type_node, arg, t2));

10195

10196         return unify (tparms, targs, t1, t, strict);

10197       }

10198        /* Else fall through.  */

10199

10200     default :

10201       if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm))))

10202       {

10203

10204         /* We're looking at an expression. This can happen with

10205           something like:

10206   

10207             template <int I>

10208                void foo(S<I>, S<I + 2>);

10209

10210           This is a "nondeduced context":

10211

10212           [deduct.type]

10213   

10214           The nondeduced contexts are:

10215

10216           --A type that is a template-id in which one or more of

10217            the template-arguments is an expression that references

10218             a template-parameter. 

10219

10220           In these cases, we assume deduction succeeded, but don't

10221           actually infer any unifications.  */

10222

10223         if (!uses_template_parms (parm)

10224              && !template_args_equal (parm, arg))

10225           return 1;

10226         else

10227           return 0;

10228       }

10229       sorry ("use of `%s' in template type unification",

10230              tree_code_name [(int) TREE_CODE (parm)]);

10231       return 1;

10232   }

10233 }

 

最后,如果是一个构成非推导上下文的表达式,则进入 default 块。 [temp.deduct.type] 的条款 4 给出了标准的定义。这里仅是其中之一,其余的在 9789 switch 块的开头来处理。

 

try_one_overload (continue)

 

9421    /* First make sure we didn't deduce anything that conflicts with

9422      explicitly specified args.  */

9423    for (i = nargs; i--; )

9424    {

9425      tree elt = TREE_VEC_ELT (tempargs, i);

9426      tree oldelt = TREE_VEC_ELT (orig_targs, i);

9427

9428      if (elt == NULL_TREE)

9429        continue ;

9430       else if (uses_template_parms (elt))

9431      {

9432        /* Since we're unifying against ourselves, we will fill in template

9433          args used in the function parm list with our own template parms.

9434           Discard them.  */

9435        TREE_VEC_ELT (tempargs, i) = NULL_TREE;

9436        continue ;

9437      }

9438      else if (oldelt && ! template_args_equal (oldelt, elt))

9439        return 0;

9440    }

9441

9442    for (i = nargs; i--; )

9443    {

9444      tree elt = TREE_VEC_ELT (tempargs, i);

9445

9446      if (elt)

9447        TREE_VEC_ELT (targs, i) = elt;

9448    }

9449

9450    return 1;

9451 }

 

如果这对形参 / 实参的推导成功,在这一点上, tempargs 包含了这一次推导的实参,而 orig_targs 包含了之前推导的实参。如果两者对应的项都不为空,且不依赖于模板参数,它们必须是相同的。如果一切顺利,最后把 tempargs 中的结果合并入 targs

记得 try_one_overload 是被 resolve_overloaded_unification 调用来推导被怀疑是重载的指针的参数。而对于其他的参数,它们被 type_unification_real 9229 行的代码块处理。注意 9240 行, len 来自参数 xlen ,如果它大于 0 ,则指定了在成功返回前需要考虑的函数参数的个数。如果已成功处理所有参数,我们来到如下的代码中。

 

type_unification_real (continue)

 

9243     /* Fail if we've reached the end of the parm list, and more args

9244      are present, and the parm list isn't variadic.  */

9245    if (args && args != void_list_node && parms == void_list_node)

9246      return 1;

9247    /* Fail if parms are left and they don't have default values.  */

9248    if (parms

9249        && parms != void_list_node

9250        && TREE_PURPOSE (parms) == NULL_TREE)

9251      return 1;

9252

9253   done:

9254    if (!subr)

9255      for (i = 0; i < ntparms; i++)

9256        if (TREE_VEC_ELT (targs, i) == NULL_TREE)

9257        {

9258          tree tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));

9259

9260          /* If this is an undeduced nontype parameter that depends on

9261            a type parameter, try another pass; its type may have been

9262            deduced from a later argument than the one from which

9263            this parameter can be deduced.  */

9264          if (TREE_CODE (tparm) == PARM_DECL

9265             && uses_template_parms (TREE_TYPE (tparm))

9266             && !saw_undeduced++)

9267            goto again;

9268

9269          if (!allow_incomplete)

9270            error ("incomplete type unification");

9271          return 2;

9272        }

9273    return 0;

9274 }

 

在上面 type_unification_real 的最后一部分中,在 9254 行的 subr ,如果非 0 ,表示 type_unification_real 正在递归调用中,这个情形,如我们前面所见,是内层模板参数依赖于外层模板参数。但对于最外层的模板,所有的模板参数都必须被推导出来。

如果有未推导的参数,而且它是函数的形参,考虑以下例子:

template <class T> void func (int a[sizeof (T)], T t) {}

int main () {

    int a[sizeof (int)];

    func (a, int(5));

    return 0;

}

在第一轮推导中,第一个形参无法推导出来,因为那时 T 尚未知。那么它将满足上面 9264 行的条件,通过 9267 行的 goto 语句再进行一轮推导。与上一轮不同的是, targs 中增加了上一轮推导的结果,现在 T 已知,因而顺利地推导出第一个形参。

如果推导成功,推导出的实参被放入 targs ,那么该模板的具现将由下面的 instantiate_template 产生(记得如果该具现已经产生,这个函数只是返回这个对象)。

 

add_template_candidate_real (continue)

 

2063    if (i != 0)

2064      return NULL;

2065

2066    fn = instantiate_template (tmpl, targs, tf_none);

2067    if (fn == error_mark_node)

2068      return NULL;

2069

2070    /* In [class.copy]:

2071

2072      A member function template is never instantiated to perform the

2073      copy of a class object to an object of its class type. 

2074

2075      It's a little unclear what this means; the standard explicitly

2076      does allow a template to be used to copy a class. For example,

2077      in :

2078

2079         struct A {

2080           A (A&);

2081           template <class T> A(const T&);

2082         };

2083         const A f ();

2084         void g () { A a (f ()); }

2085        

2086      the member template will be used to make the copy. The section

2087      quoted above appears in the paragraph that forbids constructors

2088      whose only parameter is (a possibly cv-qualified variant of) the

2089      class type, and a logical interpretation is that the intent was

2090      to forbid the instantiation of member templates which would then

2091      have that form.  */

2092    if (DECL_CONSTRUCTOR_P (fn) && list_length (arglist) == 2)

2093    {

2094      tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);

2095      if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),

2096                                ctype))

2097        return NULL;

2098    }

2099

2100    if (obj != NULL_TREE)

2101      /* Aha, this is a conversion function.  */

2102      cand = add_conv_candidate (candidates, fn, obj, access_path,

2103                              conversion_path, arglist);

2104    else

2105      cand = add_function_candidate (candidates, fn, ctype,

2106                                 arglist, access_path,

2107                                 conversion_path, flags);

2108    if (DECL_TI_TEMPLATE (fn) != tmpl)

2109      /* This situation can occur if a member template of a template

2110        class is specialized. Then, instantiate_template might return

2111        an instantiation of the specialization, in which case the

2112        DECL_TI_TEMPLATE field will point at the original

2113        specialization. For example:

2114

2115          template <class T> struct S { template <class U> void f(U);

2116                                   template <> void f(int) {}; };

2117          S<double> sd;

2118          sd.f(3);

2119

2120        Here, TMPL will be template <class U> S<double>::f(U).

2121        And, instantiate template will give us the specialization

2122         template <> S<double>::f(int). But, the DECL_TI_TEMPLATE field

2123        for this will point at template <class T> template <> S<T>::f(int),

2124        so that we can find the definition. For the purposes of

2125        overload resolution, however, we want the original TMPL.  */

2126      cand->template = tree_cons (tmpl, targs, NULL_TREE);

2127    else

2128      cand->template = DECL_TEMPLATE_INFO (fn);

2129

2130    return cand;

2131 }

 

在【 3 】的 207 页,进一步解释了 2070 行的注释:

因为一个模板构造函数不可能是一个拷贝构造函数,这样一个模板的存在不能压制拷贝构造函数的隐式声明。模板构造函数与其他构造函数,包括拷贝构造函数,一起参予重载解析,并且一个模板构造函数可以被用于拷贝一个对象,如果它能提供比其它构造函数更好的匹配。

通过这个检查,这个具现后的模板函数就是合资格的候选者; 2100 行的 obj NULL 则表明是根据提供的类型,而不是对象,来找到候选者(因此 add_function_candidate 关注的是指定的源类型及目标类型,而 add_conv_candidate 则关注指定的对象及目标类型;而在这里是查找转换指定类型的函数,这就是为什么这里只调用 add_function_candidate )。回到 build_user_type_conversion_1 ,接下来的工作与找到转换操作符后的情况类似。

 

build_user_type_conversion_1 (continue)

 

2420    if (convs)

2421      args = build_tree_list (NULL_TREE, build_this (expr));

2422

2423    for (; convs; convs = TREE_CHAIN (convs))

2424    {

2425      tree fns;

2426      tree conversion_path = TREE_PURPOSE (convs);

2427      int convflags = LOOKUP_NO_CONVERSION;

2428

2429      /* If we are called to convert to a reference type, we are trying to

2430        find an lvalue binding, so don't even consider temporaries. If

2431        we don't find an lvalue binding, the caller will try again to

2432        look for a temporary binding.  */

2433      if (TREE_CODE (totype) == REFERENCE_TYPE)

2434         convflags |= LOOKUP_NO_TEMP_BIND;

2435       

2436      for (fns = TREE_VALUE (convs); fns; fns = OVL_NEXT (fns))

2437      {

2438        tree fn = OVL_CURRENT (fns);

2439     

2440        /* [over.match.funcs] For conversion functions, the function

2441          is considered to be a member of the class of the implicit

2442          object argument for the purpose of defining the type of

2443          the implicit object parameter.

2444

2445          So we pass fromtype as CTYPE to add_*_candidate.  */

2446

2447        if (TREE_CODE (fn) == TEMPLATE_DECL)

2448          cand = add_template_candidate (&candidates, fn, fromtype,

2449                                     NULL_TREE,

2450                                     args, totype,

2451                                     TYPE_BINFO (fromtype),

2452                                     conversion_path,

2453                                     flags,

2454                                     DEDUCE_CONV);

2455        else

2456          cand = add_function_candidate (&candidates, fn, fromtype,

2457                                     args,

2458                                     TYPE_BINFO (fromtype),

2459                                     conversion_path,

2460                                     flags);

2461

2462        if (cand)

2463        {

2464          tree ics = implicit_conversion (totype,

2465                                   TREE_TYPE (TREE_TYPE (cand->fn)),

2466                                   0, convflags);

2467

2468          cand->second_conv = ics;

2469         

2470          if (ics == NULL_TREE)

2471            cand->viable = 0;

2472          else if (candidates->viable == 1 && ICS_BAD_FLAG (ics))

2473            cand->viable = -1;

2474        }

2475       }

2476    }

 

不像可以作为转换转换函数的构造函数,转换操作符可以返回与目标类型不同的类型,不过它们必须可以通过 2464 行的 implicit_conversion 来匹配,而这个转换在 2468 行被记录为 second_conv (比较对于构造函数,在 2417 行的 IDENTITY_CONV )。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值