GCC-3.4.6源代码学习笔记(149)

5.13.1.1.3.        引用类型的转换

如果目标类型是引用类型(参见 implicit_conversion 1106 行),这是由【 3 】条文 13.3.3 .1.4 “引用绑定” [over.ics.ref ] 所指定的引用绑定的情形。

1.  当一个引用类型的形参直接绑定( 8.5.3 )到一个实参表达式,其隐式转换序列是恒等转换,除非该实参表达式的类型是形参类型的一个派生类,这时其隐式转换序列是一个派生类到基类的转换( 13.3.3.1 )。 [ 例子:

struct A {};

struct B : public A {} b;

int f(A&);

int f(B&);

int i = f(b); // Calls f(B&), an exact match, rather than

// f(A&), a conversion

例子结束 ] 如果该形参直接绑定到应用在该实参表达式的一个转换函数的结果,其隐式转换序列是一个用户定义转换( 13.3.3 .1.2 ),其中的第二标准转换序列或者是一个恒等转换,或者,如果该转换函数返回该形参类型的一个派生类的实体,是派生类到基类的转换。

  2.  当一个引用类型的形参不是直接绑定到一个实参表达式,其转换序列被要求根据 13.3.3 .1 (亦即,隐式转换序列)把实参表达式转换到该引用的援引类型。在概念上,这个转换序列负责通过该实参表达式拷贝初始化一个该引用援引类型的临时对象。最顶层的 cv- 限定的差别被归入初始化本身,而不构成一个转换。

  3.  一个标准转换序列不能形成,如果要求绑定一个非常量引用到一个右值(除了在绑定一个隐含对象参数;参见在 13.3.1 中对这个情形的特殊规则)。 [ 注意:这意味着, 例如,如果一个候选函数具有一个非常量引用参数(隐含对象参数以外),并且对应的实参是一个临时对象,或为了初始化这个引用要求一个临时对象(参见 8.5.3 ]

  4.   不过,绑定一个引用到一个特定的实参的其他限制不影响一个标准转换序列的构成。 [ 例如:一个具有 int 引用参数的函数可以是一个可行候选,即便对应的实参是一个 int 的位域。隐式转换序列把 int 位域作为一个 int 左值处理,并查找形参的一个精确匹配。如果是通过重载解析来选择,这样这个函数的调用将是非法的,因为禁止绑定一个非常量的引用到一个位域( 8.5.3 ]

5.  一个引用到一个与引用兼容,带有更多限定的表达式的绑定,会影响一个标准转换序列的等级;参考 13.3.3 .2 8.5.3

 

940    static tree

941    reference_binding (tree rto, tree rfrom, tree expr, int flags)                                  in call.c

942    {

943      tree conv = NULL_TREE;

944      tree to = TREE_TYPE (rto);

945      tree from = rfrom;

946      bool related_p;

947      bool compatible_p;

948      cp_lvalue_kind lvalue_p = clk_none;

949   

950      if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))

951      {

952        expr = instantiate_type (to, expr, tf_none);

953        if (expr == error_mark_node)

954          return NULL_TREE;

955        from = TREE_TYPE (expr);

956      }

5.13.1.1.3.1.  重载引用的解析

如果被援引的目标类型是一个函数或方法的类型,并且被传入的实参表达式一个重载,其类型是 unknown_type_node 并且使得 type_unknown_p 成立(它可能是一个 baselink template-id )。这也需要为该实参确定正确的候选者。

下面的函数将实例化在中 rhs 给定的表达式的类型,来匹配由 lhstype 给定的类型。

 

6001 tree

6002 instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)                           in class.c

6003 {

6004    tsubst_flags_t flags_in = flags;

6005   

6006    flags &= ~tf_ptrmem_ok;

6007   

6008    if (TREE_CODE (lhstype) == UNKNOWN_TYPE)

6009    {

6010      if (flags & tf_error)

6011        error ("not enough type information");

6012      return error_mark_node;

6013    }

6014

6015    if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))

6016    {

6017      if (same_type_p (lhstype, TREE_TYPE (rhs)))

6018        return rhs;

6019      if (flag_ms_extensions

6020         && TYPE_PTRMEMFUNC_P (lhstype)

6021         && !TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))

6022        /* Microsoft allows `A::f' to be resolved to a

6023          pointer-to-member.  */

6024        ;

6025      else

6026      {

6027        if (flags & tf_error)

6028          error ("argument of type `%T' does not match `%T'",

6029               TREE_TYPE (rhs), lhstype);

6030        return error_mark_node;

6031      }

6032    }

 

看到 6015 行的条件如果满足, rhs 的类型是确实已知的,它必须与目标类型( lhstype )相同;否则不匹配的类型 rhs lhs 会导致一个错误。如果 rhs TREE_TYPE 中具有 unknown_type_node NULL ,这表示有多个表达式适合 rhs ,就需要由 lhs 的类型来确定最后胜出者。

正如 6042 行的注释所提到的,在 6047 行开始的 SWITCH 块用于区分这是哪种指向函数的指针(事实上也包括引用)。

在下面 6072 行的 NOP_EXPR ,它用于表示不要求任何代码产生的转换。例如,一个‘ char* ’到一个‘ int* ’的转换不要求产生任何代码;这样的一个转换由一个 NOP_EXPR 来代表。其唯一的操作数是要被转换的表达式。从一个指针到一个引用的转换也是由一个 NOP_EXPR 来表示。如果我们来到这个分支, NOP_EXPR TREE_TYPE 必须是 NULL 或者 unknown_type_node 来显示多种选择。在剥除这个顶层的 NOP_EXPR 之后,需要通过设置其操作数的 TREE_TYPE unknown_type_node ,来保留这个显示不确定性的信息。

 

instantiate_type (continue)

 

6034    if (TREE_CODE (rhs) == BASELINK)

6035      rhs = BASELINK_FUNCTIONS (rhs);

6036

6037    /* We don't overwrite rhs if it is an overloaded function.

6038      Copying it would destroy the tree link.  */

6039    if (TREE_CODE (rhs) != OVERLOAD)

6040      rhs = copy_node (rhs);

6041

6042    /* This should really only be used when attempting to distinguish

6043      what sort of a pointer to function we have. For now, any

6044      arithmetic operation which is not supported on pointers

6045      is rejected as an error.  */

6046

6047    switch (TREE_CODE (rhs))

6048    {

6049      case TYPE_EXPR:

6050      case CONVERT_EXPR:

6051      case SAVE_EXPR:

6052      case CONSTRUCTOR:

6053      case BUFFER_REF:

6054        abort ();

6055        return error_mark_node;

6056

6057      case INDIRECT_REF:

6058      case ARRAY_REF:

6059      {

6060        tree new_rhs;

6061

6062        new_rhs = instantiate_type (build_pointer_type (lhstype),

6063                               TREE_OPERAND (rhs, 0), flags);

6064        if (new_rhs == error_mark_node)

6065          return error_mark_node;

6066

6067        TREE_TYPE (rhs) = lhstype;

6068        TREE_OPERAND (rhs, 0) = new_rhs;

6069        return rhs;

6070      }

6071

6072      case NOP_EXPR:

6073        rhs = copy_node (TREE_OPERAND (rhs, 0));

6074        TREE_TYPE (rhs) = unknown_type_node;

6075        return instantiate_type (lhstype, rhs, flags);

6076

6077      case COMPONENT_REF:

6078      {

6079        tree addr = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);

6080

6081        if (addr != error_mark_node

6082           && TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))

6083          /* Do not lose object's side effects.  */

6084          addr = build (COMPOUND_EXPR, TREE_TYPE (addr),

6085                     TREE_OPERAND (rhs, 0), addr);

6086        return addr;

6087      }

6088

6089      case OFFSET_REF:

6090        rhs = TREE_OPERAND (rhs, 1);

6091        if (BASELINK_P (rhs))

6092          return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags_in);

6093

6094        /* This can happen if we are forming a pointer-to-member for a

6095          member template.  */

6096        my_friendly_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0);

6097

6098        /* Fall through.  */

6099

6100       case TEMPLATE_ID_EXPR:

6101      {

6102        tree fns = TREE_OPERAND (rhs, 0);

6103        tree args = TREE_OPERAND (rhs, 1);

6104

6105        return

6106           resolve_address_of_overloaded_function (lhstype, fns, flags_in,

6107                                              /*template_only=*/ true,

6108                                              args);

6109      }

6110

6111      case OVERLOAD:

6112      case FUNCTION_DECL:

6113        return

6114            resolve_address_of_overloaded_function (lhstype, rhs, flags_in,

6115                                             /*template_only=*/ false,

6116                                             /*explicit_targs=*/ NULL_TREE);

6117

6118      case TREE_LIST:

6119        /* Now we should have a baselink.  */

6120        my_friendly_assert (BASELINK_P (rhs), 990412);

6121

6122        return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags);

6123

6124      case CALL_EXPR:

6125        /* This is too hard for now.  */

6126        abort ();

6127        return error_mark_node;

6128

6129      case PLUS_EXPR:

6130      case MINUS_EXPR:

6131      case COMPOUND_EXPR:

6132        TREE_OPERAND (rhs, 0)

6133              = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);

6134        if (TREE_OPERAND (rhs, 0) == error_mark_node)

6135          return error_mark_node;

6136        TREE_OPERAND (rhs, 1)

6137              = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);

6138        if (TREE_OPERAND (rhs, 1) == error_mark_node)

6139          return error_mark_node;

6140

6141        TREE_TYPE (rhs) = lhstype;

6142        return rhs;

6143

6144      case MULT_EXPR:

6145      case TRUNC_DIV_EXPR:

6146      case FLOOR_DIV_EXPR:

6147      case CEIL_DIV_EXPR:

6148      case ROUND_DIV_EXPR:

6149      case RDIV_EXPR:

6150      case TRUNC_MOD_EXPR:

6151      case FLOOR_MOD_EXPR:

6152      case CEIL_MOD_EXPR:

6153      case ROUND_MOD_EXPR:

6154      case FIX_ROUND_EXPR:

6155      case FIX_FLOOR_EXPR:

6156      case FIX_CEIL_EXPR:

6157      case FIX_TRUNC_EXPR:

6158      case FLOAT_EXPR:

6159      case NEGATE_EXPR:

6160      case ABS_EXPR:

6161      case MAX_EXPR:

6162      case MIN_EXPR:

6163

6164      case BIT_AND_EXPR:

6165      case BIT_IOR_EXPR:

6166      case BIT_XOR_EXPR:

6167      case LSHIFT_EXPR:

6168      case RSHIFT_EXPR:

6169      case LROTATE_EXPR:

6170      case RROTATE_EXPR:

6171

6172      case PREINCREMENT_EXPR:

6173      case PREDECREMENT_EXPR:

6174      case POSTINCREMENT_EXPR:

6175      case POSTDECREMENT_EXPR:

6176        if (flags & tf_error)

6177          error ("invalid operation on uninstantiated type");

6178        return error_mark_node;

6179

6180      case TRUTH_AND_EXPR:

6181      case TRUTH_OR_EXPR:

6182      case TRUTH_XOR_EXPR:

6183      case LT_EXPR:

6184      case LE_EXPR:

6185      case GT_EXPR:

6186      case GE_EXPR:

6187      case EQ_EXPR:

6188      case NE_EXPR:

6189      case TRUTH_ANDIF_EXPR:

6190      case TRUTH_ORIF_EXPR:

6191      case TRUTH_NOT_EXPR:

6192        if (flags & tf_error)

6193          error ("not enough type information");

6194        return error_mark_node;

6195

6196      case COND_EXPR:

6197        if (type_unknown_p (TREE_OPERAND (rhs, 0)))

6198        {

6199          if (flags & tf_error)

6200            error ("not enough type information");

6201          return error_mark_node;

6202        }

6203        TREE_OPERAND (rhs, 1)

6204            = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);

6205        if (TREE_OPERAND (rhs, 1) == error_mark_node)

6206          return error_mark_node;

6207        TREE_OPERAND (rhs, 2)

6208            = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), flags);

6209        if (TREE_OPERAND (rhs, 2) == error_mark_node)

6210          return error_mark_node;

6211

6212        TREE_TYPE (rhs) = lhstype;

6213        return rhs;

6214

6215      case MODIFY_EXPR:

6216         TREE_OPERAND (rhs, 1)

6217            = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);

6218        if (TREE_OPERAND (rhs, 1) == error_mark_node)

6219          return error_mark_node;

6220

6221        TREE_TYPE (rhs) = lhstype;

6222        return rhs;

6223       

6224      case ADDR_EXPR:

6225      {

6226        if (PTRMEM_OK_P (rhs))

6227          flags |= tf_ptrmem_ok;

6228       

6229        return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);

6230      }

6231      case ENTRY_VALUE_EXPR:

6232        abort ();

6233        return error_mark_node;

6234

6235      case ERROR_MARK:

6236        return error_mark_node;

6237

6238      default :

6239        abort ();

6240        return error_mark_node;

6241    }

6242 }

 

上面的代码清楚地显示了关注的是指定类别节点哪个操作数(为表达式构建节点的函数,例如, build_binary_op ,将把操作数统一到同一个类型。因此对于表达式“ ptr+5 ”( ptr 是类型“ int* ”),这个表达式构建函数将把‘ 5 ’提升为类型“ int* ”)。

如果该重载是合法的(为 TEMPLATE_ID_EXPR FUNCITON_DECL ,或 OVERLOAD ),它需要被解析以找出匹配者;显然,多于一个的匹配会导致二义性的问题。看到下面的参数 explicit_targs 仅用于模板的匹配,它保存了显式给定的模板实参。

3 】,条文 13.4 “重载函数地址”( [over.over] ),给出了这个语法成分的意义和用法,连同例子。

1.  一个不带参数的重载函数名,在特定上下文中,被解析为一个函数,指向重载函数集中一个特定函数的函数的指针,或指向成员函数的指针。一个函数模板名被视为,在这样的上下文中,命名了一个重载函数集。被选中的函数,其类型与该上下文所要求的目标类型相匹配。这个目标类型可以是

要被初始化的一个对象或引用( 8.5 8.5.3 ),

一个赋值的左手侧( 5.17 ),

一个函数的一个参数( 5.2.2 ),

一个用户定义操作符的一个参数( 13.5 ),

一个函数,运算符函数,转换函数的返回值( 6.6.3 ),

一个显式类型转换( 5.2.3 5.2.9, 5.4 ),或者

一个非类型模板参数( 14.3.2 )。

该重载函数名之前可以是 & 操作符。一个重载函数名,在那些没有列出的上下文中,不能不带参数来使用。 [ 注意:包围该重载函数名的任意多余括号对被忽略( 5.1 ]

2.  如果这个名字是一个函数模板,执行模板实参推导( 14.8.2 .2 ),并且如果实参推导成功,产生的模板实参列表被用于产生一个函数模板特化,这个特化被加入这个正在关注的重载函数集中。

3.  非成员函数及静态成员函数匹配的目标类型为“函数指针”或“函数引用”。非静态成员函数匹配的目标类型是“成员函数指针”;成员指针中的函数类型用于,从重载成员函数集中,选择成员函数。如果一个非静态成员函数被选中,对该重载函数名的一个引用被要求具有一个成员指针的形式,如 5.3.1 中描述的那样。

4.  如果选中了多于一个函数,如果这个集包含了非模板函数,这个集中的函数模板特化都被淘汰;给定函数模板特化 F1 ,如果在这个集中包含了第二个函数模板特化,其函数模板的特化程度,根据 14.5.5 .2 的偏序规则,比 F1 的函数模板的特化程度高,淘汰 F1 。在这样的淘汰之后,应该只留下一个中选的函数。

5.  [ 例子:

int f(double);

int f(int);

int (*pfd)(double) = &f; // selects f(double)

int (*pfi)(int) = &f; // selects f(int)

int (*pfe)(...) = &f; // error: type mismatch

int (&rfi)(int) = f; // selects f(int)

int (&rfd)(double) = f; // selects f(double)

void g() {

(int (*)(int))&f; // cast expression as selector

}

pfe 的初始化是非法的,因为没有定义具有类型 int(…) f() ,而不是因为二义性。另一个例子,

struct X {

int f(int);

static int f(long);

};

int (X::*p1)(int) = &X::f; // OK

int (*p2)(int) = &X::f; // error: mismatch

int (*p3)(long) = &X::f; // OK

int (X::*p4)(long) = &X::f; // error: mismatch

int (X::*p5)(int) = &(X::f); // error: wrong syntax for pointer to member

int (*p6)(long) = &(X::f); // OK

例子结束 ]

6.   [ 注意:如果 f() g() 都是重载函数,解析 f(&g) ,或相当的表达式 f(g) ,必须考虑可能性的叉积( cross product ]

7.  [ 注意:这里没有一个函数指针到另一个函数指针的标准转换(条文 4 )。特别是,即使 B D 的一个公有基类,我们有

D* f();

B* (*p1)() = &f; // error

void g(D*);

void (*p2)(B*) = &g; // error

注意结束 ]

 

5723 static tree

5724 resolve_address_of_overloaded_function (tree target_type,                           in class.c

5725                                    tree overload,

5726                                    tsubst_flags_t flags,

5727                                    bool template_only,

5728                                     tree explicit_targs)

5729 {

5730    /* Here's what the standard says:

5731      

5732      [over.over]

5733

5734      If the name is a function template, template argument deduction

5735      is done, and if the argument deduction succeeds, the deduced

5736      arguments are used to generate a single template function, which

5737      is added to the set of overloaded functions considered.

5738

5739      Non-member functions and static member functions match targets of

5740      type "pointer-to-function" or "reference-to-function." Nonstatic

5741      member functions match targets of type "pointer-to-member

5742      function;" the function type of the pointer to member is used to

5743      select the member function from the set of overloaded member

5744      functions. If a nonstatic member function is selected, the

5745      reference to the overloaded function name is required to have the

5746      form of a pointer to member as described in 5.3.1.

5747

5748      If more than one function is selected, any template functions in

5749      the set are eliminated if the set also contains a non-template

5750      function, and any given template function is eliminated if the

5751      set contains a second template function that is more specialized

5752       than the first according to the partial ordering rules 14.5.5.2.

5753      After such eliminations, if any, there shall remain exactly one

5754      selected function.  */

5755

5756    int is_ptrmem = 0;

5757    int is_reference = 0;

5758    /* We store the matches in a TREE_LIST rooted here. The functions

5759      are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy

5760      interoperability with most_specialized_instantiation.  */

5761    tree matches = NULL_TREE;

5762    tree fn;

5763

5764     /* By the time we get here, we should be seeing only real

5765      pointer-to-member types, not the internal POINTER_TYPE to

5766      METHOD_TYPE representation.  */

5767    my_friendly_assert (!(TREE_CODE (target_type) == POINTER_TYPE

5768                     && (TREE_CODE (TREE_TYPE (target_type))

5769                          == METHOD_TYPE)), 0);

5770

5771    my_friendly_assert (is_overloaded_fn (overload), 20030910);

5772   

5773    /* Check that the TARGET_TYPE is reasonable.  */

5774    if (TYPE_PTRFN_P (target_type))

5775      /* This is OK.  */ ;

5776    else if (TYPE_PTRMEMFUNC_P (target_type))

5777      /* This is OK, too.  */

5778      is_ptrmem = 1;

5779    else if (TREE_CODE (target_type) == FUNCTION_TYPE)

5780    {

5781       /* This is OK, too. This comes from a conversion to reference

5782        type.  */

5783      target_type = build_reference_type (target_type);

5784      is_reference = 1;

5785    }

5786    else

5787    {

5788      if (flags & tf_error)

5789        error ("/

5790             cannot resolve overloaded function `%D' based on conversion to type `%T'",

5791             DECL_NAME (OVL_FUNCTION (overload)), target_type);

5792      return error_mark_node;

5793    }

5794   

5795    /* If we can find a non-template function that matches, we can just

5796      use it. There's no point in generating template instantiations

5797      if we're just going to throw them out anyhow. But, of course, we

5798      can only do this when we don't *need* a template function.  */

5799    if (!template_only)

5800    {

5801      tree fns;

5802

5803      for (fns = overload; fns; fns = OVL_NEXT (fns))

5804      {

5805        tree fn = OVL_CURRENT (fns);

5806        tree fntype;

5807

5808        if (TREE_CODE (fn) == TEMPLATE_DECL)

5809          /* We're not looking for templates just yet.  */

5810          continue ;

5811

5812        if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)

5813           != is_ptrmem)

5814          /* We're looking for a non-static member, and this isn't

5815            one, or vice versa.  */

5816          continue ;

5817

5818        /* Ignore anticipated decls of undeclared builtins.  */

5819        if (DECL_ANTICIPATED (fn))

5820          continue ;

5821

5822        /* See if there's a match.  */

5823        fntype = TREE_TYPE (fn);

5824        if (is_ptrmem)

5825          fntype = build_ptrmemfunc_type (build_pointer_type (fntype));

5826        else if (!is_reference)

5827          fntype = build_pointer_type (fntype);

5828

5829        if (can_convert_arg (target_type, fntype, fn))

5830          matches = tree_cons (fn, NULL_TREE, matches);

5831      }

5832    }

 

记得重载被串接在一个以 OVERLOAD 节点开头的链表中,不过在这个头部之后的节点分别包含了 FUNCTION_DECL 节点,它在 5805 行由 OVL_CURRENT 获取。然后,在 5823 行的 fntype 将是确定的 FUNCTION_TYPE ,而不是 unknown_type_node 。因此从它构建指针类型。对于这些类型, can_convert_arg 将检查该类型是否可以被隐式地转换到 target_type ,并且在处理这个指针转换的 standard_conversion 中,在 619 行,我们可以看到函数指针要求精确匹配,就像上面例子所显示的那样。

而在重载函数中,非模板函数优于模板函数,如果找到了非模板函数,就忽略所有的模板函数。如果我们不能找到匹配的非模板函数,那么我们就要查找匹配的模板函数,我们将进入下面 5837 行的 IF 块。

 

resolve_address_of_overloaded_function (continue)

 

5834    /* Now, if we've already got a match (or matches), there's no need

5835      to proceed to the template functions. But, if we don't have a

5836      match we need to look at them, too.  */

5837    if (!matches)

5838    {

5839      tree target_fn_type;

5840      tree target_arg_types;

5841      tree target_ret_type;

5842      tree fns;

5843

5844      if (is_ptrmem)

5845        target_fn_type

5846            = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type));

5847      else

5848        target_fn_type = TREE_TYPE (target_type);

5849      target_arg_types = TYPE_ARG_TYPES (target_fn_type);

5850      target_ret_type = TREE_TYPE (target_fn_type);

5851

5852      /* Never do unification on the 'this' parameter.  */

5853      if (TREE_CODE (target_fn_type) == METHOD_TYPE)

5854        target_arg_types = TREE_CHAIN (target_arg_types);

5855     

5856      for (fns = overload; fns; fns = OVL_NEXT (fns))

5857      {

5858        tree fn = OVL_CURRENT (fns);

5859        tree instantiation;

5860        tree instantiation_type;

5861        tree targs;

5862

5863        if (TREE_CODE (fn) != TEMPLATE_DECL)

5864          /* We're only looking for templates.  */

5865           continue ;

5866

5867        if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)

5868           != is_ptrmem)

5869          /* We're not looking for a non-static member, and this is

5870            one, or vice versa.  */

5871          continue ;

5872

5873        /* Try to do argument deduction.  */

5874        targs = make_tree_vec (DECL_NTPARMS (fn));

5875        if (fn_type_unification (fn, explicit_targs, targs,

5876                           target_arg_types, target_ret_type,

5877                           DEDUCE_EXACT, -1) != 0)

5878          /* Argument deduction failed.  */

5879          continue ;

5880

5881        /* Instantiate the template.  */

5882        instantiation = instantiate_template (fn, targs, flags);

5883        if (instantiation == error_mark_node)

5884          /* Instantiation failed.  */

5885          continue ;

5886

5887        /* See if there's a match.  */

5888        instantiation_type = TREE_TYPE (instantiation);

5889        if (is_ptrmem)

5890          instantiation_type =

5891             build_ptrmemfunc_type (build_pointer_type (instantiation_type));

5892        else if (!is_reference)

5893          instantiation_type = build_pointer_type (instantiation_type);

5894        if (can_convert_arg (target_type, instantiation_type, instantiation))

5895          matches = tree_cons (instantiation, fn, matches);

5896      }

5897

5898      /* Now, remove all but the most specialized of the matches.  */

5899      if (matches)

5900      {

5901        tree match = most_specialized_instantiation (matches);

5902

5903        if (match != error_mark_node)

5904          matches = tree_cons (match, NULL_TREE, NULL_TREE);

5905       }

5906    }

 

在前一节,我们已经看过了模板实参推导。这里我们就不麻烦再看一遍了。

 

resolve_address_of_overloaded_function (continue)

 

5908 Now we should have exactly one function in MATCHES.  */

5909    if (matches == NULL_TREE)

5910    {

5911      /* There were *no* matches.  */

5912      if (flags & tf_error)

5913      {

5914        error ("no matches converting function `%D' to type `%#T'",

5915             DECL_NAME (OVL_FUNCTION (overload)),

5916             target_type);

5917

5918         /* print_candidates expects a chain with the functions in

5919          TREE_VALUE slots, so we cons one up here (we're losing anyway,

5920          so why be clever?).  */

5921        for (; overload; overload = OVL_NEXT (overload))

5922          matches = tree_cons (NULL_TREE, OVL_CURRENT (overload),

5923                             matches);

5924           

5925        print_candidates (matches);

5926      }

5927      return error_mark_node;

5928    }

5929    else if (TREE_CHAIN (matches))

5930    {

5931      /* There were too many matches.  */

5932

5933      if (flags & tf_error)

5934      {

5935        tree match;

5936

5937        error ("converting overloaded function `%D' to type `%#T' is ambiguous",

5938             DECL_NAME (OVL_FUNCTION (overload)),

5939             target_type);

5940

5941        /* Since print_candidates expects the functions in the

5942          TREE_VALUE slot, we flip them here.  */

5943        for (match = matches; match; match = TREE_CHAIN (match))

5944          TREE_VALUE (match) = TREE_PURPOSE (match);

5945

5946        print_candidates (matches);

5947      }

5948       

5949      return error_mark_node;

5950    }

5951

5952    /* Good, exactly one match. Now, convert it to the correct type.  */

5953    fn = TREE_PURPOSE (matches);

5954

5955    if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)

5956       && !(flags & tf_ptrmem_ok) && !flag_ms_extensions )

5957    {

5958      static int explained;

5959       

5960      if (!(flags & tf_error))

5961        return error_mark_node;

5962

5963      pedwarn ("assuming pointer to member `%D'", fn);

5964      if (!explained)

5965       {

5966        pedwarn ("(a pointer to member can only be formed with `&%E')", fn);

5967        explained = 1;

5968      }

5969    }

5970

5971    /* If we're doing overload resolution purely for the purpose of

5972      determining conversion sequences, we should not consider the

5973      function used. If this conversion sequence is selected, the

5974      function will be marked as used at this point.  */

5975    if (!(flags & tf_conv))

5976      mark_used (fn);

5977

5978    if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))

5979      return build_unary_op (ADDR_EXPR, fn, 0);

5980    else

5981    {

5982      /* The target must be a REFERENCE_TYPE. Above, build_unary_op

5983        will mark the function as addressed, but here we must do it

5984        explicitly.  */

5985      cxx_mark_addressable (fn);

5986

5987      return fn;

5988    }

5989 }

 

最后,需要把合格的查找结果标记为可取址,这是对代码产生有重要意义的信息。而由该函数返回的 fn 是匹配的重载。并且这个返回值在 952 行被保存入 expr 。而 from 955 行被更新到这个类型。

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值