作者khoguan (Khoguan Phuann)
看板C_and_CPP
标题Re: 请问一个关於iterator的问题...
时间Mon Aug 8 20:39:52 2005
※ 引述《freaky (jon)》之铭言:
: 事实上这牵涉到 C++ Standard 里的一个目前处於草案阶段的议题
: (415. Template deduction does not cause instantiation),
: 也就是规定不需要在 template deduction 过程中做具现化的动作。
: 提案人 John Spicer 认为要 compiler 在 template argument deduction
: 过程中去进行伺机具现化 (speculative instantiations) 是不合理的,
: 而他所取用的例子刚好就是 function template "std::distance<>()"。
: 不过他认为正因为这个例子并不在 deduction failure 所列举的情况之中,
: compiler 应该回报错误。
: 之後另外一个草案
: (488. Local types, overload resolution, and template argument deduction)
: 就如何处理这个问题提出了三种解决办法。一是在 overload resolution 时产生
: 错误。方法二是在 type-deduction 时产生错误。方法三是除非 overload
: resolution 的结果需要用到这个无法 instantiate 的 instance,否则不会产生
: 错误。最近一次的开会 (2005年四月) 讨论倾向采用第二种方法。
是的,这两个 core language issues 我也注意到了。
但为了避免治丝益棼,所以未提。 :-)
issue #415 和这里的例子可说并无差别,不过 #488 则有点出入,
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#488
它是特别针对 "instantiating a function (template) declaration with
a local type as a template type-parameter" 到底该怎麽处理而发。
^^^^^^^^^^^^
: ※ 引述《khoguan (Khoguan Phuann)》之铭言:
: ...略。
: : 真正的问题点并不发生在这个决定要选哪一个函式(也就是
: : overload resolution)的时间点上,而是在更早之前。也就
: : 是编译过程根本就还没进行到 overload resolution的阶段
: : 就出错了。
: ...略。
: : 所以除了原po定义的那个 global scope distance() 以外,
: : 编译器还会去找到 std namespace 中的 distance(), 因为
: : 原po在呼叫 distance 时,所给的参数是 vector<int> 而
: : vector 又是宣告於 std namespace 中,所以被直接或间接
: : include 进来的 std namespace中所有的函式名称,只要叫
: : 做 distance() 都会被找到。因为找到的 distance() 是个
: : function template, 所以要先做 template argument deduction
: : 推导成功後,才会将产生的 template instantiation 加到
: : candidate functions set中,准备进一步做 overload
: : resolution.
: ...略。
: : 编译器需要确定这个东西到底是不是有效的 type, 如果最终的结果
: : 是无效的 type 那麽 template argument deduction 就失败,这个
: : 函式就不会加入 candidate functions set中,这种「失败」并不会
: : 产生编译错误。
: : 问题是为了确定它有没有效,编译器必须先做一个动作,就是用
: : vector<int> 来 instantiate iterator_traits<> 这个 class template,
: : 然後再看产生的 class 中有没有宣告 differenct_type 这个型别。
: ...以下略。
: 看来目前 gcc 和 EDG-based compiler 的处理方式比较接近方法二,
: VC.net 2003 则用了第三种方法,也就是本例不会发生编译错误。
嗯,GCC, Comeau (on-line), VC. Net 2003 这三种环境
我都试过的。它们都会产生编译错误,都是「抱怨」说 vector<int>
并未提供 iterator_category 这种 type.
方法二,所谓的 "Treat this as a type-deduction failure"
如果真是这样处理的话,那反而可以通过编译。因为 type-deduction
failure 就会导致那个函式版本被排除在 overload set 之外,
不会有编译错误,即是所谓的 SFINAE. 当然,如果最後找不
到任何符合的函式版本,就会有编译错误,不过,那是「後话」了 ^_^
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.227.252.32