上传cppreference
This commit is contained in:
229
web/cppreference-zh/chmhelp/cpp-language-adl.html
Normal file
229
web/cppreference-zh/chmhelp/cpp-language-adl.html
Normal file
@@ -0,0 +1,229 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
||||
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>实参依赖查找</title>
|
||||
<link rel="stylesheet" href="ext.css" />
|
||||
<link rel="stylesheet" href="site_modules.css" />
|
||||
</head>
|
||||
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_language_adl skin-cppreference2 action-view cpp-navbar">
|
||||
<div id="cpp-content-base">
|
||||
<div id="content"><a id="top"></a>
|
||||
<h1 id="firstHeading" class="firstHeading">实参依赖查找</h1>
|
||||
<div id="bodyContent">
|
||||
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-language.html">language</a></span></div>
|
||||
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
||||
<p>实参依赖查找(argument-dependent lookup),又称 ADL 或 Koenig 查找,是一组对<a href="cpp-language-operator_other.html">函数调用表达式</a>(包括对<a href="cpp-language-operators.html">重载运算符</a>的隐式函数调用)中的无限定的函数名进行查找的规则。在通常<a href="cpp-language-lookup.html">无限定名字查找</a>所考虑的作用域和命名空间之外,还在其各个实参的命名空间中查找这些函数。</p>
|
||||
<div class="t-example">
|
||||
<p>实参依赖查找使得使用定义于不同命名空间的运算符成为可能。例如:</p>
|
||||
<div class="t-example-live-link"></div>
|
||||
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
||||
<div class="cpp source-cpp">
|
||||
<pre class="de1"><span class="co2">#include <iostream></span>
|
||||
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
||||
<span class="br0">{</span>
|
||||
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Test<span class="es1">\n</span>"</span><span class="sy4">;</span> <span class="co1">// 全局命名空间中没有 operator<<,但 ADL 检验 std 命名空间,</span>
|
||||
<span class="co1">// 因为左实参在 std 命名空间中</span>
|
||||
<span class="co1">// 并找到 std::operator<<(std::ostream&, const char*)</span>
|
||||
operator<span class="sy1"><<</span><span class="br0">(</span><a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a>, <span class="st0">"Test<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 同上,用函数调用记法</span>
|
||||
|
||||
<span class="co1">// 然而,</span>
|
||||
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> endl<span class="sy4">;</span> <span class="co1">// 错误:'endl' 未在此命名空间中声明。</span>
|
||||
<span class="co1">// 这不是对 endl() 的函数调用,所以不适用 ADL</span>
|
||||
|
||||
endl<span class="br0">(</span><a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK:这是函数调用:ADL 检验 std 命名空间,</span>
|
||||
<span class="co1">// 因为 endl 的实参在 std 中,并找到了 std::endl</span>
|
||||
|
||||
<span class="br0">(</span>endl<span class="br0">)</span><span class="br0">(</span><a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 错误:'endl' 未声明于此命名空间。</span>
|
||||
<span class="co1">// 子表达式 (endl) 不是函数调用表达式</span>
|
||||
<span class="br0">}</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<h3><span class="mw-headline" id=".E7.BB.86.E8.8A.82">细节</span></h3>
|
||||
<p>首先,如果通常的<a href="cpp-language-lookup.html">无限定查找</a>所生成的集合含有下列任何内容,那么不考虑实参依赖查找:</p>
|
||||
<div class="t-li1"><span class="t-li">1)</span> 类成员的声明</div>
|
||||
<div class="t-li1"><span class="t-li">2)</span> 块作用域的(非 <a href="cpp-language-namespace.html#using_.E5.A3.B0.E6.98.8E">using 声明</a>的)函数声明</div>
|
||||
<div class="t-li1"><span class="t-li">3)</span> 任何非函数或函数模板的声明(例如函数对象或另一变量,其名字与正在查找的函数名冲突)</div>
|
||||
<p>否则,对于每个函数调用表达式中的实参,检验其类型,以确定它将向查找所添加的<i>命名空间与类的关联集</i>。</p>
|
||||
<div class="t-li1"><span class="t-li">1)</span> 对于基础类型的实参,命名空间与类的关联集为空集</div>
|
||||
<div class="t-li1"><span class="t-li">2)</span> 对于类类型(含联合体)的实参,集合由以下组成:</div>
|
||||
<div class="t-li2"><span class="t-li">a)</span> 该类自身</div>
|
||||
<div class="t-li2"><span class="t-li">b)</span> 其所有直接与间接基类</div>
|
||||
<div class="t-li2"><span class="t-li">c)</span> 如果该类是<a href="cpp-language-nested_types.html">另一类的成员</a>,该外围类</div>
|
||||
<div class="t-li2"><span class="t-li">d)</span> 添加到集合的各个类的最内层外围命名空间</div>
|
||||
<div class="t-li1"><span class="t-li">3)</span> 对于类型为<a href="cpp-language-class_template.html">类模板</a>的特化的实参,在上述关于类的规则外,还检验以下类型,并将其所关联的类与命名空间添加到集合中:</div>
|
||||
<div class="t-li2"><span class="t-li">a)</span> 为各类型模板形参提供的所有模板实参的类型(跳过非类型模板形参和模板模板形参)</div>
|
||||
<div class="t-li2"><span class="t-li">b)</span> 以任何模板模板实参为其中成员的命名空间</div>
|
||||
<div class="t-li2"><span class="t-li">c)</span> 以任何模板模板实参为其中成员的类(如果它们是类成员模板)</div>
|
||||
<div class="t-li1"><span class="t-li">4)</span> 对于任何枚举类型的实参,向集合中添加该枚举类型的声明的最内层外围命名空间。如果该枚举类型是类成员,那么向集合中添加该类。</div>
|
||||
<div class="t-li1"><span class="t-li">5)</span> 对于 T 的指针或指向 T 的数组的指针类型的实参,检验类型 T 并向集合中添加其类与命名空间的关联集合。</div>
|
||||
<div class="t-li1"><span class="t-li">6)</span> 对于函数类型的实参,检验各函数形参类型与函数返回值类型,并向集合中添加它们的类与命名空间的关联集合。</div>
|
||||
<div class="t-li1"><span class="t-li">7)</span> 对于指向类 X 的成员函数 F 的指针类型的实参,检验各函数形参类型、函数返回值类型及类 X,并向集合中添加它们的类与命名空间的关联集合。</div>
|
||||
<div class="t-li1"><span class="t-li">8)</span> 对于指向类 X 的数据成员 T 的指针类型的实参,检验该成员类型和类型 X,并向集合添加它们的类与命名空间的关联集合。</div>
|
||||
<div class="t-li1"><span class="t-li">9)</span> 如果实参是<a href="cpp-language-overloaded_address.html">一组重载函数(或函数模板)的名字或取址表达式</a>,那么检验重载集合中的每个函数,并向集合添加其类与命名空间的关联集合。</div>
|
||||
<div class="t-li2"><span class="t-li">a)</span> 另外,如果以<a href="cpp-language-templates.html#.E6.A8.A1.E6.9D.BF.E6.A0.87.E8.AF.86">模板标识</a>(带模板实参的模板名)指名重载集,那么检验其所有类型模板实参与模板模板实参(但不包括非类型模板实参),并向集合添加其类与命名空间的关联集合。</div>
|
||||
<table class="t-rev-begin">
|
||||
<tr class="t-rev t-since-cxx11">
|
||||
<td>
|
||||
<p>如果类与命名空间的关联集合中的任何命名空间是<a href="cpp-language-namespace.html">内联命名空间</a>,那么向集合中添加其外围命名空间。</p>
|
||||
<p>如果类与命名空间的关联集合中的任何命名空间直接含有内联命名空间,那么向集合中添加该内联命名空间。</p>
|
||||
</td>
|
||||
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>在确定命名空间与类的关联集合后,为了进一步的 ADL 处理,忽略此集中所有于类中找到的声明,但不包括命名空间作用域的友元函数及函数模板,陈述于后述点 2。</p>
|
||||
<p>根据下列特殊规则,将通过常规<a href="cpp-language-lookup.html">无限定查找</a>所找到的声明的集合,与通过 ADL 所生成的关联集合的所有元素中找到的声明集合进行合并:</p>
|
||||
<div class="t-li1"><span class="t-li">1)</span> 忽略关联命名空间中的 <a href="cpp-language-namespace.html#using_.E6.8C.87.E4.BB.A4">using 指令</a></div>
|
||||
<div class="t-li1"><span class="t-li">2)</span> 声明于关联类中的命名空间作用域的友元函数(及函数模板)通过 ADL 可见,即使它们通过普通查找不可见。</div>
|
||||
<div class="t-li1"><span class="t-li">3)</span> 忽略除函数与函数模板外的所有名字(不会与变量之间发生冲突)</div>
|
||||
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
||||
<p>因为实参依赖查找,定义于相同命名空间的非成员函数和非成员运算符被认为是该类公开接口的一部分(如果它们被 ADL 找到)<sup id="cite_ref-1" class="reference"><a href="cpp-language-adl.html#cite_note-1">[1]</a></sup>。</p>
|
||||
ADL 是在泛型代码中为交换两个对象而建立的手法能成立的原因:
|
||||
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
||||
<div class="cpp source-cpp">
|
||||
<pre class="de1"><span class="kw1">using</span> <a href="cpp-algorithm-swap.html"><span class="kw1599">std::<span class="me2">swap</span></span></a><span class="sy4">;</span>
|
||||
swap<span class="br0">(</span>obj1, obj2<span class="br0">)</span><span class="sy4">;</span></pre></div>
|
||||
</div>
|
||||
因为直接调用 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-algorithm-swap.html"><span class="kw1599">std::<span class="me2">swap</span></span></a><span class="br0">(</span>obj1, obj2<span class="br0">)</span></span></span> 不会考虑用户定义的 swap() 函数,它可能在与 obj1 或 obj2 类型之定义相同的空间定义,而仅调用无限定的 <span class="t-c"><span class="mw-geshi cpp source-cpp">swap<span class="br0">(</span>obj1, obj2<span class="br0">)</span></span></span>会在没有用户定义重载时无法调用任何函数。特别是 <span class="t-lc"><a href="cpp-algorithm-iter_swap.html">std::iter_swap</a></span> 与所有其他标准库算法在处理<a href="cpp-named_req-Swappable.html"><span style="font-style:italic">可交换</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Swappable)</span></a> 类型时使用此手段。
|
||||
<p>名字查找规则使得在全局或用户定义命名空间中声明对来自 std 命名空间的类型进行操作的运算符变得不切实际,例如,对于 <span class="t-lc"><a href="cpp-container-vector.html">std::vector</a></span> 或 <span class="t-lc"><a href="cpp-utility-pair.html">std::pair</a></span> 的自定义 <span class="t-c"><span class="mw-geshi cpp source-cpp">operator<span class="sy2">+</span></span></span> 或 <span class="t-c"><span class="mw-geshi cpp source-cpp">operator<span class="sy1">>></span></span></span>(除非 vector/pair 的元素类型是用户定义类型,这会将其命名空间添加到 ADL 中)。这种运算符不会从诸如标准库算法的模板实例化中被查找到。进一步细节见<a href="cpp-language-dependent_name.html">待决名</a>。</p>
|
||||
<p>ADL 能找到完全在类或类模板内定义的<a href="cpp-language-friend.html">友元函数</a>(典型为重载的运算符),即使它始终未在命名空间层次进行声明。</p>
|
||||
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
||||
<div class="cpp source-cpp">
|
||||
<pre class="de1"><span class="kw1">template</span><span class="sy1"><</span><span class="kw1">typename</span> T<span class="sy1">></span>
|
||||
<span class="kw1">struct</span> number
|
||||
<span class="br0">{</span>
|
||||
number<span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span><span class="sy4">;</span>
|
||||
<span class="kw1">friend</span> number gcd<span class="br0">(</span>number x, number y<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span> <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 类模板内的定义</span>
|
||||
<span class="br0">}</span><span class="sy4">;</span>
|
||||
<span class="co1">// 除非提供匹配声明,否则 gcd 是此命名空间的不可见成员(除非通过 ADL)</span>
|
||||
<span class="kw4">void</span> g<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
||||
number<span class="sy1"><</span><span class="kw4">double</span><span class="sy1">></span> a<span class="br0">(</span><span class="nu0">3</span><span class="br0">)</span>, b<span class="br0">(</span><span class="nu0">4</span><span class="br0">)</span><span class="sy4">;</span>
|
||||
a <span class="sy1">=</span> gcd<span class="br0">(</span>a,b<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 找到 gcd ,因为 number<double> 是关联类,</span>
|
||||
<span class="co1">// 令 gcd 于其命名空间(全局命名空间)可见</span>
|
||||
<span class="co1">// b = gcd(3,4); // 错误:gcd 不可见</span>
|
||||
<span class="br0">}</span></pre></div>
|
||||
</div>
|
||||
<table class="t-rev-begin">
|
||||
<tr class="t-rev t-until-cxx20">
|
||||
<td>
|
||||
<p>尽管普通查找找不到结果也能通过 ADL 解析函数调用,但是对带显式指定模板实参的<a href="cpp-language-function_template.html">函数模板</a>调用还是要求存在普通查找所能找到的模板声明(否则,它将是遇到未知名字后随小于号的语法错误):</p>
|
||||
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
||||
<div class="cpp source-cpp">
|
||||
<pre class="de1"><span class="kw1">namespace</span> N1 <span class="br0">{</span>
|
||||
<span class="kw1">struct</span> S <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
||||
<span class="kw1">template</span><span class="sy1"><</span><span class="kw4">int</span> X<span class="sy1">></span> <span class="kw4">void</span> f<span class="br0">(</span>S<span class="br0">)</span><span class="sy4">;</span>
|
||||
<span class="br0">}</span>
|
||||
<span class="kw1">namespace</span> N2 <span class="br0">{</span>
|
||||
<span class="kw1">template</span><span class="sy1"><</span><span class="kw1">class</span> T<span class="sy1">></span> <span class="kw4">void</span> f<span class="br0">(</span>T t<span class="br0">)</span><span class="sy4">;</span>
|
||||
<span class="br0">}</span>
|
||||
<span class="kw4">void</span> g<span class="br0">(</span>N1<span class="sy4">::</span><span class="me2">S</span> s<span class="br0">)</span> <span class="br0">{</span>
|
||||
f<span class="sy1"><</span><span class="nu0">3</span><span class="sy1">></span><span class="br0">(</span>s<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// C++20 前为语法错误(无限定查找找不到 f)</span>
|
||||
N1<span class="sy4">::</span><span class="me2">f</span><span class="sy1"><</span><span class="nu0">3</span><span class="sy1">></span><span class="br0">(</span>s<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK,有限定查找找到模板 'f'</span>
|
||||
N2<span class="sy4">::</span><span class="me2">f</span><span class="sy1"><</span><span class="nu0">3</span><span class="sy1">></span><span class="br0">(</span>s<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 错误: N2::f 不接收非类型模板形参</span>
|
||||
<span class="co1">// N1::f 不能被找到,因为 ADL 仅适用于无限定名</span>
|
||||
<span class="kw1">using</span> N2<span class="sy4">::</span><span class="me2">f</span><span class="sy4">;</span>
|
||||
f<span class="sy1"><</span><span class="nu0">3</span><span class="sy1">></span><span class="br0">(</span>s<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK:无限定查找现在找到 N2::f,</span>
|
||||
<span class="co1">// 然后因为此名无限定所以 ADL 表态并找到 N1::f</span>
|
||||
<span class="br0">}</span></pre></div>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="t-mark-rev t-until-cxx20">(C++20 前)</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>下列语境只中进行 ADL(即仅在关联的命名空间中查找):</p>
|
||||
<table class="t-rev-begin">
|
||||
<tr class="t-rev t-since-cxx11">
|
||||
<td>
|
||||
<ul>
|
||||
<li>对 <a href="cpp-language-range-for.html">范围 for</a> 循环,成员查找失败时,查找非成员函数 <code>begin</code> 与 <code>end</code></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
<ul>
|
||||
<li>从模板实例化点进行<a href="cpp-language-dependent_name.html#.E6.9F.A5.E6.89.BE.E8.A7.84.E5.88.99">待决名查找</a>。</li>
|
||||
</ul>
|
||||
<table class="t-rev-begin">
|
||||
<tr class="t-rev t-since-cxx17">
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="cpp-language-structured_binding.html">结构化绑定声明</a>对元组式类型查找非成员函数 <code>get</code></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
||||
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
|
||||
<tr>
|
||||
<td class="mbox-empty-cell"></td>
|
||||
<td class="mbox-text" style="">本节未完成<br />
|
||||
原因:更多示例</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="t-example">
|
||||
<p>来自 <a rel="nofollow" class="external free" href="http://www.gotw.ca/gotw/030.htm">http://www.gotw.ca/gotw/030.htm</a> 的示例</p>
|
||||
<div class="t-example-live-link"></div>
|
||||
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
||||
<div class="cpp source-cpp">
|
||||
<pre class="de1"><span class="kw1">namespace</span> A <span class="br0">{</span>
|
||||
<span class="kw1">struct</span> X<span class="sy4">;</span>
|
||||
<span class="kw1">struct</span> Y<span class="sy4">;</span>
|
||||
<span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span><span class="sy4">;</span>
|
||||
<span class="kw4">void</span> g<span class="br0">(</span>X<span class="br0">)</span><span class="sy4">;</span>
|
||||
<span class="br0">}</span>
|
||||
|
||||
<span class="kw1">namespace</span> B <span class="br0">{</span>
|
||||
<span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">int</span> i<span class="br0">)</span> <span class="br0">{</span>
|
||||
f<span class="br0">(</span>i<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 调用 B::f(无限递归)</span>
|
||||
<span class="br0">}</span>
|
||||
<span class="kw4">void</span> g<span class="br0">(</span>A<span class="sy4">::</span><span class="me2">X</span> x<span class="br0">)</span> <span class="br0">{</span>
|
||||
g<span class="br0">(</span>x<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 错误:在 B::g(常规查找)与 A::g(实参依赖查找)间有歧义</span>
|
||||
<span class="br0">}</span>
|
||||
<span class="kw4">void</span> h<span class="br0">(</span>A<span class="sy4">::</span><span class="me2">Y</span> y<span class="br0">)</span> <span class="br0">{</span>
|
||||
h<span class="br0">(</span>y<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 调用 B::h(无限递归):ADL 检验命名空间 A</span>
|
||||
<span class="co1">// 但是找不到 A::h,所以只采用来自常规查找的 B::h</span>
|
||||
<span class="br0">}</span>
|
||||
<span class="br0">}</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<h3><span class="mw-headline" id=".E7.BC.BA.E9.99.B7.E6.8A.A5.E5.91.8A">缺陷报告</span></h3>
|
||||
<p>下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。</p>
|
||||
<table class="dsctable" style="font-size:0.8em">
|
||||
<tr>
|
||||
<th>DR</th>
|
||||
<th>应用于</th>
|
||||
<th>出版时的行为</th>
|
||||
<th>正确行为</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a rel="nofollow" class="external text" href="https://wg21.cmeerw.net/cwg/issue33">CWG 33</a></td>
|
||||
<td>C++98</td>
|
||||
<td>当用于查找的实参是重载函数或函数模板的地址时,关联的命名空间和类未指明</td>
|
||||
<td>指明它们</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a rel="nofollow" class="external text" href="https://wg21.cmeerw.net/cwg/issue90">CWG 90</a></td>
|
||||
<td>C++98</td>
|
||||
<td>嵌套的非联合体类的类关联集不包含该类的外围类,但嵌套联合体与它的外围类关联</td>
|
||||
<td>所有嵌套类都关联对应外围类</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
||||
<ul>
|
||||
<li><a href="cpp-language-lookup.html">名字查找</a></li>
|
||||
<li><a href="cpp-language-function_template.html">模板实参推导</a></li>
|
||||
<li><a href="cpp-language-overload_resolution.html">重载决议</a></li>
|
||||
</ul>
|
||||
<h3><span class="mw-headline" id=".E5.BC.95.E7.94.A8">引用</span></h3>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="cpp-language-adl.html#cite_ref-1">↑</a></span> <span class="reference-text">H. Sutter (1998) <a rel="nofollow" class="external text" href="http://www.gotw.ca/publications/mill02.htm">"What's In a Class? - The Interface Principle"</a> in C++ Report, 10(3)</span></li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="visualClear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user