161 lines
14 KiB
HTML
161 lines
14 KiB
HTML
<!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_overloaded_address 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>除了<a href="cpp-language-operator_other.html">函数调用表达式</a>之外,重载函数的名字还可以出现在下列 7 种发生<a href="cpp-language-overload_resolution.html">重载决议</a>的语境中:</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 对象或<a href="cpp-language-reference_initialization.html">引用</a><a href="cpp-language-declarations.html">声明</a>中的<a href="cpp-language-initialization.html">初始化器</a></div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 赋值运算符的右侧</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 作为函数调用的实参</div>
|
|
<div class="t-li1"><span class="t-li">4)</span> 作为用户定义运算符的实参</div>
|
|
<div class="t-li1"><span class="t-li">5)</span> <a href="cpp-language-return.html"><code>return</code></a> 语句</div>
|
|
<div class="t-li1"><span class="t-li">6)</span> <a href="cpp-language-explicit_cast.html">显式转型</a>或 <a href="cpp-language-static_cast.html"><code>static_cast</code></a> 的实参</div>
|
|
<div class="t-li1"><span class="t-li">7)</span> 非类型<a href="cpp-language-template_parameters.html">模板实参</a></div>
|
|
<p>在每个语境中,重载函数的名字可以前附取址运算符 <code><b>&</b></code> 并且可以被一组冗余的括号所环绕。</p>
|
|
<p>在所有这些语境中,从重载集中选择的函数,是其类型与<i>目标</i>所期待的函数指针、函数引用或成员函数指针类型相匹配的函数,<i>目标</i>分别为:被初始化的对象或引用,赋值的左侧,函数或运算符的形参,函数的返回类型,转型的目标类型,以及模板形参的类型。</p>
|
|
<p>函数的形参类型和返回类型必须与目标严格匹配,不考虑隐式转换(例如,在初始化指向返回基类指针的函数的指针时,不会选择返回派生类指针的函数)。</p>
|
|
<p>如果函数名指名了某个函数模板,那么首先进行<a href="cpp-language-template_argument_deduction.html">模板实参推导</a>,且如果它成功,那么将会生成一个单独的模板特化并添加到所要考虑的重载集合中。<span class="t-rev-inl t-since-cxx20"><span>从集合中丢弃所有不满足其关联<a href="cpp-language-constraints.html">约束</a>的函数。</span> <span><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></span></span>如果集合中有多于一个函数与目标匹配,且至少一个函数是非模板,那么从考虑集合中去除模板特化。<span class="t-rev-inl t-since-cxx20"><span>对于任何一对非模板函数,如果其中一个比另一个<a href="cpp-language-constraints.html">更受约束</a>,那么从集合中丢弃受较少约束的函数。</span> <span><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></span></span>如果所有剩余候选者都是模板特化,那么当存在更特殊的模板特化时,移除<a href="cpp-language-partial_specialization.html">较不特殊</a>者。如果在各项移除之后还有多于一个候选者,那么程序非良构。</p>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<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="kw4">int</span> f<span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="nu0">1</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw4">int</span> f<span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="nu0">2</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
|
|
<span class="kw4">void</span> g<span class="br0">(</span> <span class="kw4">int</span><span class="br0">(</span><span class="sy3">&</span>f1<span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span>, <span class="kw4">int</span><span class="br0">(</span><span class="sy2">*</span>f2<span class="br0">)</span><span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span> <span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
|
|
|
|
<span class="kw1">template</span><span class="sy1"><</span> <span class="kw4">int</span><span class="br0">(</span><span class="sy2">*</span>F<span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="sy1">></span>
|
|
<span class="kw1">struct</span> Templ <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">struct</span> Foo <span class="br0">{</span>
|
|
<span class="kw4">int</span> mf<span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="nu0">3</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw4">int</span> mf<span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="nu0">4</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">struct</span> Emp <span class="br0">{</span>
|
|
<span class="kw4">void</span> operator<span class="sy1"><<</span><span class="br0">(</span><span class="kw4">int</span> <span class="br0">(</span><span class="sy2">*</span><span class="br0">)</span><span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// 1. 初始化</span>
|
|
<span class="kw4">int</span> <span class="br0">(</span><span class="sy2">*</span>pf<span class="br0">)</span><span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span> <span class="sy1">=</span> f<span class="sy4">;</span> <span class="co1">// 选择 int f(double)</span>
|
|
<span class="kw4">int</span> <span class="br0">(</span><span class="sy3">&</span>rf<span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="sy1">=</span> f<span class="sy4">;</span> <span class="co1">// 选择 int f(int)</span>
|
|
<span class="kw4">int</span> <span class="br0">(</span>Foo<span class="sy4">::</span><span class="sy2">*</span>mpf<span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="sy1">=</span> <span class="sy3">&</span>Foo<span class="sy4">::</span><span class="me2">mf</span><span class="sy4">;</span> <span class="co1">// 选择 int mf(int)</span>
|
|
|
|
<span class="co1">// 2. 赋值</span>
|
|
pf <span class="sy1">=</span> nullptr<span class="sy4">;</span>
|
|
pf <span class="sy1">=</span> <span class="sy3">&</span>f<span class="sy4">;</span> <span class="co1">// 选择 int f(double)</span>
|
|
|
|
<span class="co1">// 3. 函数实参</span>
|
|
g<span class="br0">(</span>f, f<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 为第一实参选择 int f(int)</span>
|
|
<span class="co1">// 为第二实参选择 int f(double)</span>
|
|
|
|
<span class="co1">// 4. 用户定义运算符</span>
|
|
Emp<span class="br0">{</span><span class="br0">}</span> <span class="sy1"><<</span> f<span class="sy4">;</span> <span class="co1">// 选择 int f(double)</span>
|
|
|
|
<span class="co1">// 5. 返回值</span>
|
|
<span class="kw4">auto</span> foo <span class="sy1">=</span> <span class="br0">[</span><span class="br0">]</span><span class="br0">(</span><span class="br0">)</span> <span class="sy2">-</span><span class="sy1">></span> <span class="kw4">int</span> <span class="br0">(</span><span class="sy2">*</span><span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">return</span> f<span class="sy4">;</span> <span class="co1">// 选择 int f(int)</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 6. 转型</span>
|
|
<span class="kw4">auto</span> p <span class="sy1">=</span> <span class="kw1">static_cast</span><span class="sy1"><</span><span class="kw4">int</span><span class="br0">(</span><span class="sy2">*</span><span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span><span class="sy1">></span><span class="br0">(</span>f<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 选择 int f(int)</span>
|
|
|
|
<span class="co1">// 7. 模板实参</span>
|
|
Templ<span class="sy1"><</span>f<span class="sy1">></span> t<span class="sy4">;</span> <span class="co1">// 选择 int f(int)</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.BC.95.E7.94.A8">引用</span></h3>
|
|
<div class="t-ref-std-c++20">
|
|
<ul>
|
|
<li>C++20 标准(ISO/IEC 14882:2020):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>12.5 Address of overloaded function [over.over]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c++17">
|
|
<ul>
|
|
<li>C++17 标准(ISO/IEC 14882:2017):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>16.4 Address of overloaded function [over.over]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c++14">
|
|
<ul>
|
|
<li>C++14 标准(ISO/IEC 14882:2014):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>13.4 Address of overloaded function [over.over]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c++11">
|
|
<ul>
|
|
<li>C++11 标准(ISO/IEC 14882:2011):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>13.4 Address of overloaded function [over.over]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c++03">
|
|
<ul>
|
|
<li>C++03 标准(ISO/IEC 14882:2003):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>13.4 Address of overloaded function [over.over]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c++98">
|
|
<ul>
|
|
<li>C++98 标准(ISO/IEC 14882:1998):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>13.4 Address of overloaded function [over.over]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|