<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2023-02-10" />
  <title>Proposed resolution for CWG2692 Static and explicit object
member functions with the same parameter-type-lists</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.csl-block{margin-left: 1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      .sourceCode { overflow: visible; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
a.self-link {
position: absolute;
top: 0;
left: calc(-1 * (3.5rem - 26px));
width: calc(3.5rem - 26px);
height: 2em;
text-align: center;
border: none;
transition: opacity .2s;
opacity: .5;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Proposed resolution for
CWG2692 Static and explicit object member functions with the same
parameter-type-lists</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2797R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2023-02-10</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      Core<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Gašper Ažman<br>&lt;<a href="mailto:gasper.azman@gmail.com" class="email">gasper.azman@gmail.com</a>&gt;<br>
      Barry Revzin<br>&lt;<a href="mailto:barry.revzin@gmail.com" class="email">barry.revzin@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#abstract" id="toc-abstract"><span class="toc-section-number">1</span> Abstract<span></span></a></li>
<li><a href="#discussion" id="toc-discussion"><span class="toc-section-number">2</span> Discussion<span></span></a>
<ul>
<li><a href="#the-actual-problem-explained" id="toc-the-actual-problem-explained"><span class="toc-section-number">2.1</span> The actual problem,
explained<span></span></a></li>
</ul></li>
<li><a href="#resolution" id="toc-resolution"><span class="toc-section-number">3</span> Resolution<span></span></a></li>
<li><a href="#caveats-if-we-chose-option-1" id="toc-caveats-if-we-chose-option-1"><span class="toc-section-number">4</span> Caveats if we chose option
1<span></span></a></li>
<li><a href="#other-related-issues" id="toc-other-related-issues"><span class="toc-section-number">5</span> Other related
issues<span></span></a></li>
<li><a href="#does-this-break-code" id="toc-does-this-break-code"><span class="toc-section-number">6</span> Does this break
code?<span></span></a></li>
<li><a href="#drive-by-wording-changes" id="toc-drive-by-wording-changes"><span class="toc-section-number">7</span> Drive-by wording
changes<span></span></a></li>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">8</span> Wording<span></span></a></li>
<li><a href="#other-considerations" id="toc-other-considerations"><span class="toc-section-number">9</span> Other
considerations<span></span></a>
<ul>
<li><a href="#getting-the-pointers-to-these-functions" id="toc-getting-the-pointers-to-these-functions"><span class="toc-section-number">9.1</span> Getting the pointers to these
functions<span></span></a></li>
<li><a href="#mangling" id="toc-mangling"><span class="toc-section-number">9.2</span> Mangling<span></span></a></li>
</ul></li>
<li><a href="#acknowledgements" id="toc-acknowledgements"><span class="toc-section-number">10</span>
Acknowledgements<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">11</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This document proposes a resolution to <span class="citation" data-cites="CWG2692">[<a href="#ref-CWG2692" role="doc-biblioref">CWG2692</a>]</span>. This also touches the proposed
resolution to <span class="citation" data-cites="CWG2687">[<a href="#ref-CWG2687" role="doc-biblioref">CWG2687</a>]</span>.</p>
<h1 data-number="2" id="discussion"><span class="header-section-number">2</span> Discussion<a href="#discussion" class="self-link"></a></h1>
<p>Consider the example</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> A <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="dt">void</span> f<span class="op">(</span>A<span class="op">)</span>; <span class="co">// #A</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> f<span class="op">(</span><span class="kw">this</span> A<span class="op">)</span>;   <span class="co">// #B</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="dt">void</span> e<span class="op">(</span>A <span class="kw">const</span><span class="op">&amp;)</span>; <span class="co">// #C</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> e<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;</span>;         <span class="co">// #D</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> g<span class="op">()</span> <span class="op">{</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// static + explicit memfn</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">(&amp;</span>A<span class="op">::</span>f<span class="op">)(</span>A<span class="op">())</span>; <span class="co">// #1</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    f<span class="op">(</span>A<span class="op">())</span>;       <span class="co">// #2</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">(&amp;</span>A<span class="op">::</span>f<span class="op">)()</span>;    <span class="co">// #3</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    <span class="co">// static + implicit memfn</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>    <span class="op">(&amp;</span>A<span class="op">::</span>e<span class="op">)(</span>A<span class="op">())</span>; <span class="co">// #4</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>    e<span class="op">(</span>A<span class="op">())</span>;       <span class="co">// #5</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">(&amp;</span>A<span class="op">::</span>e<span class="op">)()</span>;    <span class="co">// #6</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> h<span class="op">()</span> <span class="op">{</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>  <span class="co">// static + explicit memfn</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>  <span class="op">(&amp;</span>A<span class="op">::</span>f<span class="op">)(</span>A<span class="op">())</span>; <span class="co">// #7</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>  f<span class="op">(</span>A<span class="op">())</span>;       <span class="co">// ill-formed</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>  <span class="op">(&amp;</span>A<span class="op">::</span>f<span class="op">)()</span>;    <span class="co">// #8</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>  <span class="co">// static + implicit memfn</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>  <span class="op">(&amp;</span>A<span class="op">::</span>e<span class="op">)(</span>A<span class="op">())</span>; <span class="co">// #9</span></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>  e<span class="op">(</span>A<span class="op">())</span>;       <span class="co">// ill-formed</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>  <span class="op">(&amp;</span>A<span class="op">::</span>e<span class="op">)()</span>;    <span class="co">// #10</span></span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 data-number="2.1" id="the-actual-problem-explained"><span class="header-section-number">2.1</span> The actual problem, explained<a href="#the-actual-problem-explained" class="self-link"></a></h2>
<p>The options:</p>
<ul>
<li>Option 1: <em>#1</em> and <em>#2</em>, <em>#4</em> and <em>#5</em>
behave the same, <em>#3</em> and <em>#6</em> are ill-formed.</li>
<li>Option 2: <em>#1</em> is ambiguous, <em>#2</em> calls the static,
<em>#4</em> is ambiguous, <em>#5</em> calls the static.</li>
</ul>
<p>Explanations of the two options:</p>
<p><strong>Option 1:</strong> the synthesized argument list for the
<em>unqualified function call</em>
<code class="sourceCode default">(&amp;A::f)</code> is actually
<code class="sourceCode default">((A&amp;)*this, A{})</code> (per
<span>12.2.2.2.2
<a href="https://wg21.link/over.call.func">[over.call.func]</a></span>/3),
therefore only <em>#A</em> is a viable candidate for <em>#1</em> and
<em>#2</em>.</p>
<p><strong>Option 2:</strong> If
<code class="sourceCode default">(&amp;A::e)</code> instead of resolving
on the original overload set first takes the address of <em>all</em> of
the overload set, and then resolves the call expression on those
pointers, then <em>#1</em> and <em>#4</em> are ambiguous, and do
something different than <em>#2</em> and <em>#3</em>.</p>
<h1 data-number="3" id="resolution"><span class="header-section-number">3</span> Resolution<a href="#resolution" class="self-link"></a></h1>
<p>EWG chose option 2. Call-of-address-of-overload-set expressions like
<code class="sourceCode default">(&amp;function-id-expression)(expr-list)</code>
decay the overload set to pointers to the elements of the overload set
before choosing best-match.</p>
<p><span>12.2.2.2.1
<a href="https://wg21.link/over.match.call.general">[over.match.call.general]</a></span>/2
just refers to <span>12.2.2.2.2
<a href="https://wg21.link/over.call.func">[over.call.func]</a></span>/3.</p>
<h1 data-number="4" id="caveats-if-we-chose-option-1"><span class="header-section-number">4</span> Caveats if we chose option 1<a href="#caveats-if-we-chose-option-1" class="self-link"></a></h1>
<p>The proposed resolution (of affirming the status quo) means that
there is a difference in this case:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> identity<span class="op">(</span><span class="kw">auto</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> x; <span class="op">}</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> f<span class="op">(</span><span class="kw">this</span> C<span class="op">)</span>; <span class="co">// note: not an overload set</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  </span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> g<span class="op">()</span> <span class="op">{</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>            <span class="op">(&amp;</span>C<span class="op">::</span>f<span class="op">)(</span>C<span class="op">{})</span>; <span class="co">// always ill-formed</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    identity<span class="op">(&amp;</span>C<span class="op">::</span>f<span class="op">)(</span>C<span class="op">{})</span>; <span class="co">// OK</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<h1 data-number="5" id="other-related-issues"><span class="header-section-number">5</span> Other related issues<a href="#other-related-issues" class="self-link"></a></h1>
<p>The core issue proposes to diagnose #A and #B as conflicting. We
propose not doing that. It would create an inconsistency between
explicit and implicit member functions, as well as remove a useful
feature, since a call expression for either is never ambiguous. EWG
affirmed this too.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> l<span class="op">()</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  A<span class="op">::</span>f<span class="op">(</span>A<span class="op">{})</span>; <span class="co">// calls #A</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  A<span class="op">{}.</span>f<span class="op">()</span>;   <span class="co">// calls #B </span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h1 data-number="6" id="does-this-break-code"><span class="header-section-number">6</span> Does this break code?<a href="#does-this-break-code" class="self-link"></a></h1>
<p>No, there is already implementation divergence with implicit member
functions.</p>
<p>GCC, clang and icx reject <em>#4</em> and <em>#6</em> with:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>&quot;reference to overloaded function could not be resolved, did you mean to call it?&quot;</span></code></pre></div>
<p>MSVC accepts <em>#4</em> and rejects <em>#6</em>:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>MSVC error C2352: &#39;B::f&#39;: a call of a non-static member function requires an object.</span></code></pre></div>
<p>ICC accepts both <em>#4</em> and <em>#6</em>. Our reading of
<span>12.2.2.2.2
<a href="https://wg21.link/over.call.func">[over.call.func]</a></span>/3
is that MSVC is correct.</p>
<h1 data-number="7" id="drive-by-wording-changes"><span class="header-section-number">7</span> Drive-by wording changes<a href="#drive-by-wording-changes" class="self-link"></a></h1>
<p>Due to the fact that approximately nobody is aware that
<em>unqualified function call</em> and <em>qualified function call</em>
are terms which have nothing to do with <em>unqualified-ids</em> or
<em>qualified-ids</em>, we may want to fix the term of “(un)qualified
function call” in the standard (editorially) and replace it with
<em>objectish function call</em> for
<code class="sourceCode default">x.f()</code> and
<code class="sourceCode default">px-&gt;f()</code>, and <em>nonobjectish
function call</em> for <code class="sourceCode default">N::f()</code>,
due to the general confusion of “qualified” referring to
<code class="sourceCode default">pobj-&gt;</code> or
<code class="sourceCode default">obj.</code> instead of namespace
qualification.</p>
<p>The authors would like to thank Davis for his amazing terminological
suggestion.</p>
<p>These terms are only used 1 and 2 times, respectively, in
<span>12.2.2.2.2
<a href="https://wg21.link/over.call.func">[over.call.func]</a></span>,
so they don’t have to be short.</p>
<p>The reasoning for the new term is that
<code class="sourceCode default">-&gt;</code> and
<code class="sourceCode default">.</code> are operators for <em>class
member access</em>.</p>
<p>If the fact that <code class="sourceCode default">N::f(x)</code> is
an <em>unqualified function call</em> surprises you, then you agree.</p>
<h1 data-number="8" id="wording"><span class="header-section-number">8</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>Thanks to Davis Herring, the plan is:</p>
<ol type="1">
<li>Do not merely strip the
<code class="sourceCode default">&amp;</code> in <span>12.2.2.2.1
<a href="https://wg21.link/over.match.call.general">[over.match.call.general]</a></span>/2;
remember that it was there.</li>
<li>Do not add an implicit object parameter in <span>12.2.2.1
<a href="https://wg21.link/over.match.funcs.general">[over.match.funcs.general]</a></span>/2
for static member functions when called with
<code class="sourceCode default">&amp;</code>.</li>
<li>Do not add an implied object argument in <span>12.2.2.2.2
<a href="https://wg21.link/over.call.func">[over.call.func]</a></span>/3
if the <code class="sourceCode default">&amp;</code> was there.</li>
<li>Back in <span>12.2.2.2.1
<a href="https://wg21.link/over.match.call.general">[over.match.call.general]</a></span>/2,
adjust the rejection mechanism.</li>
<li>Ensure that <span>7.6.1.3
<a href="https://wg21.link/expr.call">[expr.call]</a></span>/7 does the
right thing (it does).</li>
</ol>
<p>In <span>7.5.4.1
<a href="https://wg21.link/expr.prim.id.general">[expr.prim.id.general]</a></span>/3:</p>
<p>An <em>id-expression</em> that denotes a non-static data member or
<span class="rm" style="color: #bf0303"><del>non-static</del></span><span class="add" style="color: #006e28"><ins>implicit object</ins></span> member function
of a class can only be used:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(3.1)</a></span> as
part of a class member access in which the object expression refers to
the member’s class or a class derived from that class, or</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.2)</a></span> to
form a pointer to member (<span>7.6.2.2
<a href="https://wg21.link/expr.unary.op">[expr.unary.op]</a></span>),
or</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.3)</a></span> if
that <em>id-expression</em> denotes a non-static data member and it
appears in an unevaluated operand.</li>
</ul>
<p>[Example 3:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> S <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>      <span class="dt">int</span> m;</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> i <span class="op">=</span> <span class="kw">sizeof</span><span class="op">(</span>S<span class="op">::</span>m<span class="op">)</span>;           <span class="co">// OK</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> j <span class="op">=</span> <span class="kw">sizeof</span><span class="op">(</span>S<span class="op">::</span>m <span class="op">+</span> <span class="dv">42</span><span class="op">)</span>;      <span class="co">// OK</span></span></code></pre></div>
<p>— end example]</p>
<p>Strike <span>7.6.1.3
<a href="https://wg21.link/expr.call">[expr.call]</a></span>/2 (every
part of it is redundant with some other wording):</p>
<div class="rm" style="color: #bf0303">
<p>For a call to a non-static member function, the postfix expression
shall be an implicit (<span>11.4.3
<a href="https://wg21.link/class.mfct.non.static">[class.mfct.non.static]</a></span>,
<span>11.4.9
<a href="https://wg21.link/class.static">[class.static]</a></span>) or
explicit class member access (<span>7.6.1.5
<a href="https://wg21.link/expr.ref">[expr.ref]</a></span>) whose
<em>id-expression</em> is a function member name, or a pointer-to-member
expression (<span>7.6.4
<a href="https://wg21.link/expr.mptr.oper">[expr.mptr.oper]</a></span>)
selecting a function member; the call is as a member of the class object
referred to by the object expression. In the case of an implicit class
member access, the implied object is the one pointed to by this.</p>
</div>
<p>In <span>11.4.3
<a href="https://wg21.link/class.mfct.non.static">[class.mfct.non.static]</a></span>/2:</p>
<p>When an <em>id-expression</em> (<span>7.5.4
<a href="https://wg21.link/expr.prim.id">[expr.prim.id]</a></span>) that
is <span class="rm" style="color: #bf0303"><del>not</del></span><span class="add" style="color: #006e28"><ins>neither</ins></span> part of a
class member access syntax (<span>7.6.1.5
<a href="https://wg21.link/expr.ref">[expr.ref]</a></span>) <span class="rm" style="color: #bf0303"><del>and not used to form a pointer to
member</del></span> <span class="add" style="color: #006e28"><ins>nor
the unparenthesized operand of the unary
<span><code class="sourceCode default">&amp;</code></span>
operator</ins></span> (<span>7.6.2.2
<a href="https://wg21.link/expr.unary.op">[expr.unary.op]</a></span>) is
used where the current class is
<code class="sourceCode default">X</code> (<span>7.5.2
<a href="https://wg21.link/expr.prim.this">[expr.prim.this]</a></span>),
if name lookup (<span>6.5
<a href="https://wg21.link/basic.lookup">[basic.lookup]</a></span>)
resolves the name in the <em>id-expression</em> to a non-static non-type
member of some class <code class="sourceCode default">C</code>, and if
either the <em>id-expression</em> is potentially evaluated or
<code class="sourceCode default">C</code> is
<code class="sourceCode default">X</code> or a base class of
<code class="sourceCode default">X</code>, the <em>id-expression</em> is
transformed into a class member access expression (<span>7.6.1.5
<a href="https://wg21.link/expr.ref">[expr.ref]</a></span>) using
<code class="sourceCode default">(*this)</code> as the
postfix-expression to the left of the
<code class="sourceCode default">.</code> operator.</p>
<p>In <span>12.2.2.1
<a href="https://wg21.link/over.match.funcs.general">[over.match.funcs.general]</a></span>/2:</p>
<p>The set of candidate functions can contain both member and non-member
functions to be resolved against the same argument list.</p>
<div class="rm" style="color: #bf0303">
<p>So that argument and parameter lists are comparable within this
heterogeneous set, a member function that does not have an explicit
object parameter is considered to have an extra first parameter, called
the implicit object parameter, which represents the object for which the
member function has been called. For the purposes of overload
resolution, both static and non-static member functions have an object
parameter, but constructors do not.</p>
</div>
<div class="add" style="color: #006e28">
<p>If a member function is</p>
<ul>
<li>an implicit object member function that is not a constructor,
or</li>
<li>a static member function and the argument list includes an implied
object argument,</li>
</ul>
<p>it is considered to have an extra first parameter, called the
implicit object parameter, which represents the object for which the
member function has been called.</p>
</div>
<p>In <span>12.2.2.2.1
<a href="https://wg21.link/over.match.call.general">[over.match.call.general]</a></span>/2:</p>
<p>If the <em>postfix-expression</em> is the address of an overload set,
overload resolution is applied using that set as described above. <span class="add" style="color: #006e28"><ins>[Note: No implied object
argument is added in this case. – end note]</ins></span> If the function
selected by overload resolution is <span class="rm" style="color: #bf0303"><del>a non-static</del></span><span class="add" style="color: #006e28"><ins>an implicit object</ins></span> member
function, the program is ill-formed. [Note 1: The resolution of the
address of an overload set in other contexts is described in <span>12.3
<a href="https://wg21.link/over.over">[over.over]</a></span>. —- end
note]</p>
<p>In <span>12.2.2.2.2
<a href="https://wg21.link/over.call.func">[over.call.func]</a></span>/3:</p>
<p>In unqualified function calls, the function is named by a
<em>primary-expression</em>. The function declarations found by name
lookup (<span>6.5
<a href="https://wg21.link/basic.lookup">[basic.lookup]</a></span>)
constitute the set of candidate functions. Because of the rules for name
lookup, the set of candidate functions consists <span class="rm" style="color: #bf0303"><del>(1)</del></span><span class="add" style="color: #006e28"><ins>either</ins></span> entirely of non-member
functions or <span class="rm" style="color: #bf0303"><del>(2)</del></span> entirely of member
functions of some class <code class="sourceCode default">T</code>. In
<span class="rm" style="color: #bf0303"><del>case (1)</del></span><span class="add" style="color: #006e28"><ins>the former case or if the
<em>primary-expression</em> is the address of an overload
set</ins></span>, the argument list is the same as the
<em>expression-list</em> in the call. <span class="rm" style="color: #bf0303"><del>In case (2)</del></span><span class="add" style="color: #006e28"><ins>Otherwise</ins></span>, the argument list is
the <em>expression-list</em> in the call augmented by the addition of an
implied object argument as in a qualified function call. If the current
class is, or is derived from, <code class="sourceCode default">T</code>,
and the keyword <code class="sourceCode default">this</code>
(<span>7.5.2
<a href="https://wg21.link/expr.prim.this">[expr.prim.this]</a></span>)
refers to it, then the implied object argument is
<code class="sourceCode default">(*this)</code>. Otherwise, a contrived
object of type <code class="sourceCode default">T</code> becomes the
implied object argument; if overload resolution selects a non-static
member function, the call is ill-formed.</p>
<p>[Example 1:</p>
<div>
<div class="sourceCode" id="cb7"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>  struct C {</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    void a();</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    void b() {</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>      a();                // OK, (*this).a()</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="va">+   void c(this const C&amp;);   // #1</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="va">+   void c()&amp;;               // #2</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="va">+   static void c(int = 0);  // #3</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a><span class="va">+   void d() {</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a><span class="va">+     c();               // error: ambiguous between #2 and #3</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a><span class="va">+     (C::c)();          // error: as above</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a><span class="va">+     (&amp;(C::c))();       // error: cannot resolve address of overloaded this-&gt;C::c [over.over]</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a><span class="va">+     (&amp;C::c)(C{});      // selects #1</span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a><span class="va">+     (&amp;C::c)(*this);    // error: selects #2, and is ill-formed [over.match.call.general]/2</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a><span class="va">+     (&amp;C::c)();         // selects #3</span></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a><span class="va">+   }</span></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>    void f(this const C&amp;);</span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a>    void g() const {</span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a>      f();                // OK, (*this).f()</span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a>      f(*this);           // error: no viable candidate for (*this).f(*this)</span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a>      this-&gt;f();          // OK</span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>    static void h() {</span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a>      f();                // error: contrived object argument, but overload resolution</span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a>                          // picked a non-static member function</span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a>      f(C{});             // error: no viable candidate</span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a>      C{}.f();            // OK</span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-34"><a href="#cb7-34" aria-hidden="true" tabindex="-1"></a>    void k(this int);</span>
<span id="cb7-35"><a href="#cb7-35" aria-hidden="true" tabindex="-1"></a>    operator int() const;</span>
<span id="cb7-36"><a href="#cb7-36" aria-hidden="true" tabindex="-1"></a>    void m(this const C&amp; c) {</span>
<span id="cb7-37"><a href="#cb7-37" aria-hidden="true" tabindex="-1"></a>      c.k();              // OK</span>
<span id="cb7-38"><a href="#cb7-38" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb7-39"><a href="#cb7-39" aria-hidden="true" tabindex="-1"></a>  };</span></code></pre></div>
</div>
<p>— end example]</p>
<h1 data-number="9" id="other-considerations"><span class="header-section-number">9</span> Other considerations<a href="#other-considerations" class="self-link"></a></h1>
<h2 data-number="9.1" id="getting-the-pointers-to-these-functions"><span class="header-section-number">9.1</span> Getting the pointers to these
functions<a href="#getting-the-pointers-to-these-functions" class="self-link"></a></h2>
<p>While <code class="sourceCode default">static_cast&lt;void(*)(B const&amp;)&gt;(&amp;B::f)</code>
will work to deliver the static version, the same for
<code class="sourceCode default">A</code> will be ambiguous. This is ok,
we already have situations in the language where
<code class="sourceCode default">static_cast</code> is less powerful in
overload resolution than a call expression. The solution is to use a
lambda.</p>
<h2 data-number="9.2" id="mangling"><span class="header-section-number">9.2</span> Mangling<a href="#mangling" class="self-link"></a></h2>
<p>The resolution means that functions with an explicit object parameter
must be mangled differently than a static member function with the same
formal parameter list, which realistically should be the case
anyway.</p>
<h1 data-number="10" id="acknowledgements"><span class="header-section-number">10</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>The authors would like to thank Davis Herring, for diligently working
through all the issues and examples.</p>
<h1 data-number="11" id="bibliography"><span class="header-section-number">11</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
<div id="ref-CWG2687" class="csl-entry" role="doc-biblioentry">
[CWG2687] Matthew House. 2023-01-16. Calling an explicit object member
function via an address-of-overload-set. <a href="https://wg21.link/cwg2687"><div class="csl-block">https://wg21.link/cwg2687</div></a>
</div>
<div id="ref-CWG2692" class="csl-entry" role="doc-biblioentry">
[CWG2692] Matthew House. 2023-01-16. Static and explicit object member
functions with the same parameter-type-lists. <a href="https://wg21.link/cwg2692"><div class="csl-block">https://wg21.link/cwg2692</div></a>
</div>
</div>
</div>
</div>
</body>
</html>
