<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="author" content="P0670R2, ISO/IEC JTC1 SC22 WG21">

<link rel="stylesheet" href="http://cdn.jsdelivr.net/font-hack/2.015/css/hack.min.css"/>
<style type="text/css">
pre {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  margin-left:20pt;
  line-height: 1.1em;
  font-size: small;
}
code {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-size: small;
}
pre > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
pre > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
h3 > code {
  font-size: large;
}
body {
    color: #000000; background-color: #FFFFFF; 
    font-family: "Book Antiqua", "Times New Roman", "Times", serif;
    padding: 2em;
}
/*del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }*/
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: none;
    border-bottom: 1px solid #005100;
    color: #005100;
    line-height: 1.4em;
}
ins.edit { text-decoration: none;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
del.edit {
  text-decoration: line-through;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
span.section_name {
    float: right;
    font-weight: bold;
}

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; margin-bottom: 0.5em;}

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em;
  padding-right: 0.5em; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto;
  margin-top: 2em; margin-bottom: 2em;}

table.withBorder {
  border-top: none;
  border-left: none;
  border-right: 1px solid black;
  border-bottom: 1px solid black;
}
.withBorder th {
  border-top: 1px solid black;
  border-bottom: 1px solid black;
  border-left: 1px solid black;
/*  border-top: 2px solid black;
  border-left: 2px solid black;
  border-bottom: 1px solid black;
  border-right: 1px solid black;*/
}
.withBorder td {
  border-top: 1px solid black;
  border-left: 1px solid black;
}

table.header {
  margin-left: 0em;
  border: none;
    margin-bottom: 2em;
}
th { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em; }
td { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em;  }
</style>

<title>Static reflection of functions</title>
</head>

<body>
<table class="header">
    <tr><td>Document Number:</td> <td><b>P0670R2</b>, ISO/IEC JTC1 SC22 WG21</td></tr>
  <tr><td>Audience:</td><td>EWG, LEWG</td></tr>
   <tr><td>Date:</td><td>2017-11-08</td></tr>
  <tr><td rowspan=3>Authors:</td><td>Matúš Chochlík (chochlik@gmail.com)</td></tr>
  <tr><td>Axel Naumann (axel@cern.ch)</td></tr>
  <tr><td>David Sankel (camior@gmail.com)</td></tr>
</table>
<h1>Static reflection of functions</h1>

    <h2>Table of Contents</h2>
<nav id="TOC">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#other-proposals">Interplay with other proposals</a></li>
<li><a href="#design">Concepts and Operations</a></l>
<!--li><a href="#proposed-wording">Proposed wording</a></li-->
<li><a href="#acknowledgments">Acknowledgments</a></li>
<!--li><a href="#history">Revision history</a></li-->
<li><a href="#references">References</a></li>
</ul>
</nav>

  <!--
    <h2>&nbsp;</h2>
<blockquote>
<p></p>
</blockquote>
-->

<h2 id="introduction">Introduction</h2>
<p><a href="http://wg21.link/p0194">P0194</a> introduced static reflection for types and variables. This paper adds static reflection of functions.</p>
 
<p>Reflection proposed here behaves as follows:</p>
<pre><code>
void func(int);
void func(std::string);
using func_call_m = reflexpr(func(123));
using func_m = get_callable_t&lt;func_call_m&gt;; // reflects void func(int)
using param0_m = get_element_t&lt;0, get_parameters_t&lt;func_m&gt;&gt;;
cout &lt;&lt; get_name_v&lt;get_type_t&lt;param0_m&gt;&gt; &lt;&lt; '\n'; // prints "int"
</code></pre>

<p>The functionality introduced here allows for reflection of calls of concrete
functions. This enables, for instance, GUI generation, building a catalogue for
remote procedure calls, documentation generation, and signal/slot frameworks.
  Like P0194, this proposal omits attributes, templates, and reification
(i.e. conversion of a meta object to the base level): all warrant a separate paper.
  We would welcome a paper especially on static reflection of attributes, matching the interface-style of P0194 and this paper!
  Linkage and friends will be part of a follow-up paper to P0194; they will have a combined "effect" on P0194 and this paper.</p>

<h2 id="other-proposals">Interplay with other proposals</h2>
<p>Most notably, this proposal relies on P0194 and the Concepts TS.</p>
<p><a href="http://wg21.link/p0385">P0385</a> discusses use cases, rationale,
design decisions, and the future evolution of the proposed reflection
facility. It also has usage examples and replies to frequently asked questions.</p>


<h2 id="design">Concepts and Operations</h2>

<p>Following P0194's lead, function reflection requires a couple new concepts to restrict operations on the meta level. It builds upon the concepts introduced by P0194 and, like P0194, all declarations are inside the <code>reflect</code> namespace.

Some of the concepts below extend P0194's concepts. Whenever a concept A requires another concept B, the operations defined for concept B are also available for concept A, building a graph similar to an inheritance graph.</p>
<p>Proper wording will be provided when needed (and when P0194 has progressed through LWG, increasing to the authors' experience on wording of reflection papers); we believe that missing wording should not hinder SG7's design discussion. The wording is planned to be similar to that of P0194; specifically, it uses nested <code>type</code> and <code>value</code> entities, with the usual using declarations <code>..._t</code> and <code>..._v</code>.</p>

<h3>Extending operands of <code>reflexpr</code></h3>
<p>P0194 allows certain types and variables as operands of <code>reflexpr</code>. This paper extends this set:</p>
<ul>
  <li>invoking <code>reflexpr</code> on a function call expression generates a <code>FunctionCallExpression</code>;</li>
  <li>invoking <code>reflexpr</code> on a closure type generates a <code>Lambda</code>;</li>
  <li>invoking <code>reflexpr</code> on a parameter name generates a <code>FunctionParameter</code>;</li>
  <li>invoking <code>reflexpr</code> on a lambda capture generates a <code>LambdaCapture</code>;</li>
</ul>
<p>

The way to obtain a <code>Callable</code> might seem complicated. But instead of inventing a new syntax, for instance <code>reflexpr(foo(int,int))</code>, re-using the mechanism of matching the address of an overloaded function name <code>reflexpr((void(&amp;)(int, int))foo)</code>, or syntax similar to function definition <code>reflexpr(void foo(int,int))</code>, we rely on the existing, familiar rules for function overload resolution and generate the <code>Callable</code> only when a concrete overload is selected. This approach also works for constructors and operators, for instance <code>reflexpr(std::string())</code> reflects the call of the default constructor of <code>string</code>; <code>reflexpr(1+1)</code> reflects the call of the built-in addition operator for type <code>int</code>.
</p>


<!--
	 - FunctionParameter
  -->
<h3><code>FunctionParameter</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept FunctionParameter = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Named</code> and <code>ScopeMember</code>. Represents a function parameter. Unlike <code>Variable</code>, it does not offer a <code>get_pointer</code> interface. The name of a parameter is one of the names used in an unspecified declaration. If at least one of the declarations does not specify the parameter name, then <code>get_name</code> is allowed to return an empty string. Its scope is the <code>Callable</code> declaring this <code>FunctionParameter</code>.</dd>
<dt></dt>
<dd>Given the lack of relevance that C++ attributes to parameter names in function declarations one might ask: "o really?!" We believe that the answer is "yes": parameter names often carry significant meaning. Examples:
  <pre>
  <code>
    double Gauss(double x, double mean, double width, double height);

    void f() {
      // Don't confuse those!
      func(true /*willLeave*/,
           false /*knewWhatTheyVotedOn*/,
           false /*willBeHappyEverAfter*/);
    }
  </code>
  </pre>
  The bare combination of type and index is almost meaningless in these cases. There are many reflection applications that can benefit from this, for instance:
  <ul>
    <li>remote procedure calls identifying parameters by name;</li>
    <li>code exposing C++ functions to scripting frameworks;</li>
    <li>GUI generation, converting parameter names to text box labels;</li>
    <li>documentation generation, referencing function parameters in a meaningful way.</li>
  </ul>
  To put it differently: functions without parameter names are like classes without member names. And <code>tuple</code> is not a replacement for classes.</dd>
<dt></dt>
<dd>Another common objection is that multiple declarations could potentially
     have different parameter names ascribed. This concern is mitigated in two
     ways:

     <ol><li>Modern coding conventions have the declarations for a particular
        function showing up in exactly one header file.</li>
     <li>Modern coding conventions discourage the use of different argument
        names between function declarations (in a header) and function
        definitions (in a '.cpp' file). Dedicated compiler warnings exist to
        protecte against this case.</li>
     </ol>
</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires FunctionParameter&lt;T&gt;<br>
struct is_ellipsis;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Indicates that a <code>FunctionParameter</code> reflects an ellipsis.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires FunctionParameter&lt;T&gt;<br>
struct has_default_value;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Indicates that a <code>FunctionParameter</code> has a default value.</dd>
</dl>

<!--
	 - Callable
  -->
<h3><code>Callable</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Callable = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Named</code>, <code>ScopeMember</code> and <code>Scope</code>. Represents a function or lambda, including operators, constructors and destructors - i.e. anything this paper is dealing with.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct get_parameters;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns an <code>ObjectSequence</code> of <code>FunctionParameter</code>s of the reflected <code>Callable</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct is_constexpr;<br>
<br>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct is_noexcept;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function was declared as <code>constexpr</code> or <code>noexcept</code>, respectively.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct is_inline;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is an inline function. With <code>struct X{ inline void f(); void g() {} }</code>, <code>is_inline</code> is <code>true</code> for both <code>f</code> and <code>g</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct is_deleted;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function was defined as <code>= delete</code> before the invocation of <code>reflexpr</code>.</dd>
</dl>


<h3><code>FunctionCallExpression</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept FunctionCallExpression = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Object</code>. Reflects a call of a concrete function or other callable.
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires FunctionCallExpression&lt;T&gt;<br>
struct get_callable;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns the <code>Callable</code> that was invoked in a <code>FunctionCallExpression</code>.</dd>
</dl>


<!--
	 - Function
  -->
<h3><code>Function</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Function = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Callable</code> and <code>Typed</code>. Represents a function or lambda, excluding constructors and destructors.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Function&lt;T&gt;<br>
struct get_pointer;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns a pointer to the function. This is a pointer-to-member for non-static member functions (including lambda calls), and a function pointer otherwise. It is ill-formed to invoke this for deleted functions. Example: <code>auto p_sin = get_pointer_v&lt;get_callable_t&lt;reflexpr(sin(1.0))&gt;&gt;</code> holds the address of <code>sin(double)</code>.</dd>
</dl>


<!--
	 - RecordMemberFunction
  -->
<h3><code>RecordMemberFunction</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept RecordMemberFunction = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>RecordMember</code> and <code>Function</code>. Represents a member function, excluding constructors and destructors.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_static;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether this is a static member function.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_const;<br><br>

template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_volatile;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is declared as <code>const</code> or <code>volatile</code>, respectively.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct has_lvalueref_qualifier;<br><br>

template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct has_rvalueref_qualifier;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is declared as with a <em>ref-qualifier</em> being <code>&amp;</code> or <code>&amp;&amp;</code>, respectively.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_virtual;<br><br>

template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_pure_virtual;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is a virtual or pure virtual function, respectively. For
<pre>
  <code>
    struct A { virtual void X(); };
    struct B: A { void X(); };
  </code>
</pre>
the value of <code>is_virtual_v&lt;get_callable_t&lt;reflexpr(std::declval&lt;B&gt;().X())&gt;&gt;</code> is <code>true</code>, irrespectively of whether <code>virtual</code> is implicit of explicit.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_override;<br><br>

template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_final;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is declared as <code>override</code> or <code>final</code>, respectively.</dd>
</dl>


<!--
	 - SpecialMemberFunction
  -->
<h3><code>SpecialMemberFunction</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept SpecialMemberFunction = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>RecordMember</code>. Represents a special member function.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires SpecialMemberFunction&lt;T&gt;<br>
struct is_implicitly_declared;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the special member function is known to be implicitly declared at the point of invocation of <code>reflexpr</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires SpecialMemberFunction&lt;T&gt;<br>
struct is_defaulted;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is defined as <code>= default</code> before the invocation of <code>reflexpr</code>, independently of whether the special member function is implicitly or explicitly declared.</dd>
</dl>



<h3><code>Constructor</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Constructor = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Callable</code> and <code>RecordMember</code>. Represents a constructor. The base name of the constructor is the base name of the constructor's class. Even though the standard explicitly says that constructors do not have a name, for usability purposes (e.g. generating messages), having them state the class name is a usability improvement.</dd>
<dt></dt>
<dd>Some instances of <code>Constructor</code> might also satisfy <code>SpecialMemberFunction</code>.</dd>
</dl>

<h4>Operations</h4>


<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Constructor&lt;T&gt;<br>
struct is_explicit;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the constructor is known to be declared as <code>explicit</code>.</dd>
</dl>




<h3><code>Destructor</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Destructor = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Callable</code>, <code>SpecialMemberFunction</code> and <code>RecordMember</code>. Represents a destructor. The base name is the base name if the destructor's class, prefixed with <code>'~'</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Destructor&lt;T&gt;<br>
struct is_virtual;<br><br>

template &lt;typename T&gt;<br>
requires Destructor&lt;T&gt;<br>
struct is_pure_virtual;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the destructor is a virtual or pure virtual function, respectively. For
<pre>
  <code>
    struct A { virtual ~A(); };
    struct B: A { B(); };
  </code>
</pre>
the value of <code>is_virtual_v&lt;get_callable_t&lt;reflexpr(std::declval&lt;B&gt;.~B())&gt;&gt;</code> is <code>true</code>, irrespectively of whether <code>virtual</code> is implicit of explicit.</dd>
</dl>





<h3><code>Operator</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Operator = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Function</code>. Some instances might implement <code>RecordMemberFunction</code> or <code>SpecialMemberFunction</code>. Represents an operator. The base name is the operator "symbol", for instance <code>"+"</code>.</dd>
</dl>






<h3><code>ConversionOperator</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept ConversionOperator = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Operator</code>. Represents a conversion operator. The base name is the base name of the operator's target type, for instance <code>"int"</code>.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires ConversionOperator&lt;T&gt;<br>
struct is_explicit;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is declared as <code>explicit</code>.</dd>
</dl>







<h3><code>Lambda</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Lambda = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Function</code>. Represents a closure type, excluding those for generic lambdas. Its base name is the empty string.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Lambda&lt;T&gt;<br>
struct get_captures;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns an <code>ObjectSequence</code> of <code>LambdaCapture</code>s.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Lambda&lt;T&gt;<br>
struct uses_default_copy_capture;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the <em>capture-default</em> is <code>=</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Lambda&lt;T&gt;<br>
struct uses_default_reference_capture;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the <em>capture-default</em> is <code>&amp;</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Lambda&lt;T&gt;<br>
struct is_call_operator_const;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns <code>false</code> if the lambda was declared as <code>mutable</code>, <code>true otherwise</code>.</dd>
</dl>



<h3><code>LambdaCapture</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept LambdaCapture = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Variable</code>. Represents a lambda capture as introduced by the capture list or by capture defaults. The <code>LambdaCapture</code>'s scope is its <code>Lambda</code>.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires LambdaCapture&lt;T&gt;<br>
struct is_explicitly_captured;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the entity was captured explicitly.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires LambdaCapture&lt;T&gt;<br>
struct is_init_capture;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the entity is an <em>init-capture</em>.</dd>
</dl>




<h3>Extending <code>Record</code></h3>
<p>This proposal adds the following interfaces to the <code>Record</code> concept of P0194:</p>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_public_member_functions;<br><br>

template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_accessible_member_functions;<br><br>

template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_member_functions;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns an <code>ObjectSequence</code> of <code>RecordMemberFunctions</code>s representing a class's public member functions (for <code>get_public_member_functions</code>), member functions accessible from the point of invocation of <code>reflexpr</code> (for <code>get_accessible_member_functions</code>) and all member functions, irrespective of their accessibility (for <code>get_member_functions</code>). This includes <em>static</em> member functions, but not <em>friend</em> functions.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_constructors;<br><br>

template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_destructors;<br><br>

template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_operators;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns an <code>ObjectSequence</code> of a class's <code>Constructor</code>s, <code>Destructor</code>s and <code>Operator</code>s, respectively.</dd>
</dl>



<!--h2 id="proposed-wording">Proposed wording</h2-->

<h2 id="acknowledgments">Acknowledgments</h2>
<p>Thanks to Jackie Kay who provided valuable feedback, criticism and suggestions!</p>



<!-- h2 id="history">Revision history</h2>

<h4>Revision 1 (<a href="http://wg21.link/N3996">N3996</a>)</h4>

<p>Describes the method of static reflection
by means of compiler-generated anonymous types. Introduces the first version
of the metaobject concepts and some possibilities of their implementation.
Also includes discussion about the motivation and the design rationale for the proposal.
</p-->



<h2 id="references" class="references unnumbered">References</h2>
<div id="ref-p0385">
<p>1. <em>Static reflection. Rationale, design and evolution.</em> <a href="http://wg21.link/p0385">p0385</a></p>
</div>
<div id="ref-p0578">
<p>2. <em>Static reflection in a nutshell.</em> <a href="http://wg21.link/p0578">p0578</a></p>
</div>
</body>
</html>
