<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>

<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">

<style type="text/css">

body { color: #000000; background-color: #FFFFFF; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

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; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

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; }
th { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }

</style>

<title>Abominable Function Types</title>
</head>
<body>
<h1>Abominable Function Types</h1>

<p>
P0172R0 - 2015-11-10
</p>

<address>
Alisdair Meredith, ameredith1@bloomberg.net
</address>

<h2>Table of Contents</h2>
<ul>
<li><a href="#1.0">1 Introduction</a></li>
<li><a href="#2.0">2 Abominable Function Types</a></li>
  <ul>
  <li><a href="#2.1">2.1 Definition</a></li>
  <li><a href="#2.2">2.2 Basic Issues</a></li>
  <li><a href="#2.3">2.3 How are Abominable Function Types Used?</a></li>
  <li><a href="#2.4">2.4 How are Abominable Function Types <i>Really</i> Used?</a></li>
  <li><a href="#2.5">2.5 Why do Abominable Function Types Exist?</a></li>
  </ul>
<li><a href="#3.0">3 Concerns</a></li>
<li><a href="#4.0">4 Recommended Direction</a></li>
  <ul>
  <li><a href="#4.1">Option 1: Remove the abominations</a></li>
  <li><a href="#4.2">Option 2: Abominations are not Function</a></li>
  <li><a href="#4.3">Option 3: Make Abominations More Regular</a></li>
  <li><a href="#4.4">Option 4: Embrace in the Library</a></li>
  </ul>
</ul>


<h2><a name="1.0">1 Introduction</a></h2>
<p>
There is a dark corner of the type system that is little known other than to
compier writers, and authors of generic code who must document which types
their templates can handle.  This paper tries to shed some light in the dark
corners, and explores whether the language can be cleaned up so that good
template documentation does not drag obscure language-lawyer details into the
domain of the regular user.
</p>


<h2><a name="2.0">2 Abominable Function Types</a></h2>

<h3><a name="2.1">2.1 Definition</a></h3>
<p>
For the purposes of this paper, an <i>abominable</i> function type is the type
produced by writing a function type followed by a <i>cv-ref</i> qualifier.
</p>
<p>
Example:
</p>

<blockquote><pre>
using regular    = void();
using abominable = void() const volatile &amp;&amp;;
<pre></blockquote>

<p>
In the example above, <tt>regular</tt> names a familiar function type and
should contain no surprsies.  <tt>abominable</tt> also names a function type,
not a reference type, and despite appearances, is neither a <tt>const</tt> nor
a <tt>volatile</tt> qualified type.  There is no such thing as a
<i>cv-</i>qualified function type in the type system, and the abominable
function type is something else entirely.
</p>
<p>
Note that it is not possible to create a function that has an abominable type.
Rather, the <i>cv-ref</i> qualifier applies to the implicit <tt>*this</tt>
reference when calling a member function.  However, abominable function types
are specifically function types, and not member function types.  This is
evident from the lack of ability to specify the type of class the abominable
function would be a member of, when declaring such a function type.
</p>

<h3><a name="2.2">2.2 Basic Issues</a></h3>
<p>
The inability to create a function of such types goes deep into the language.
Given it is not possible to create a function of such a type, the language
further protects us by making it ill-formed (diagnostic required) to form a
reference or a pointer to such a type, i.e., there are no abomninable function
reference types, and no abominable function pointer types.  Take the following
example:
</p>

<blockquote><pre>
using abominable = void() const volatile &amp;&amp;;
using const_type = abominable const;
using pointer    = abominable *;      <i>// ill-formed</i>
using reference  = abominable &amp;;      <i>// ill-formed</i>
<pre></blockquote>

<p>
In this case, <tt>abominable</tt> names a function type, and as per the rules
for function types, and <tt>const_type</tt> names the same type as
<tt>abominable</tt> as <i>cv</i> qualifiers are ignored for function types.
However, unlike regular function types, the lines attempting to define
<tt>pointer</tt> and <tt>reference</tt> are ill-formed.
</p>

<h3><a name="2.3">2.3 How are Abominable Function Types Used?</a></h3>
<p>
Outside generic code, where the language syntax permits instantiating
templates on any type, how would an abominable type be used in regular code?
</p>
<p>
The only examples I have of explicitly writing these types fall into the
category of showing off knowledge of the corners of compilers, and winning
obfuscated coding contests.  I have not yet encountered the following idiom in
real-world usage outside of such scenarios.
</p>

<blockquote><pre>
class rectangle {
  public:
    using int_property = int() const;  <i>// common signature for several methods</i>

    int_property top;
    int_property left;
    int_property bottom;
    int_property right;
    int_property width;
    int_property height;

    <i>// Remaining details elided</i>
};
<pre></blockquote>

<p>
Here we declare a <tt>rectangle</tt> class with accessors for common properties
of a rectangle, which would doubtlessly compute the value, rather than store
directly, for some of these properties.  This is a very common object oriented
example so I will not labour the details.  The key is that the class author
wants to guarantee a regularity of declaration for all member access functions,
so forms an abominable function type with the desired <tt>const</tt> qualified
access, to ensure that all functions have identical signatures.
</p>

<p>
Note that this example applies to function types in general, not just
abominable function types.  However, most other examples of using function
types do not apply to abominable function types, due to their inability to form
references and pointers.  While the above idiom with regular function types is
highly unusual, even in tutorials on the esoteric, I am not aware of any such
coverage that actually uses abominable function types when demonstrating the
idiom, so even this usage is yet to be proved as more than theoretical.
</p>

<h3><a name="2.4">2.4 How are Abominable Function Types <i>Really</i> Used?</a></h3>
<p>
I run into two related uses of abominable function types in production code
bases.  The most common is writing test drivers for templates, where we want to
be sure that the template robustly handles all the types that it claims to
handle.  Testing the standard library type traits is an important use case, as
most type traits claim to handle any (complete) type.
</p>
<p>
The second use case is implementing special workarounds in templates that claim
to accept any type, or any function type.  For example, I would really like my
implementation of <tt>std::is_function_v</tt> to be this simple:
</p>

<blockquote><pre>
template &lt;typename TYPE&gt;
constexpr bool is_function_v = false;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...)&gt; = true;
<pre></blockquote>

<p>
Commonly, I will forget about functions with a C-style elipsis, which
require one further specialization:
</p>

<blockquote><pre>
template &lt;typename TYPE&gt;
constexpr bool is_function_v = false;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...)&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......)&gt; = true;
<pre></blockquote>

<p>
However, abominable functions types are still function types, so we need to
produce the result <tt>true</tt> for any abominable function type as
well:
</p>


<blockquote><pre>
template &lt;typename TYPE&gt;
constexpr bool is_function_v = false;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...)&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......)&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) &amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) &amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) &amp;&amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) &amp;&amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) const&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) const&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) const &amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) const &amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) const &amp;&amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) const &amp;&amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) volatile&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) volatile&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) volatile &amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) volatile &amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) volatile &amp;&amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) volatile &amp;&amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) const volatile&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) const volatile&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) const volatile &amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) const volatile &amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS...) const volatile &amp;&amp;&gt; = true;

template &lt;typename RESULT, typename ...ARGS&gt;
constexpr bool is_function_v&lt;RESULT(ARGS......) const volatile &amp;&amp;&gt; = true;
<pre></blockquote>

<p>
Rather than a simple primary template and two partial specializations, there
are now twenty-four partial specializations to write and test.  Note that this
paper was written before
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html">P0012R1</a>
was adopted, making exception specifications part of the type system,
potentially doubling the number of partial specializations again.
</p>

<h3><a name="2.5">2.5 Why do Abominable Function Types Exist?</a></h3>
<p>
If abominable function types have such peculiar properties, and no clear
motivating use case, why are they in the language?  The answer is that they
were not designed to be this way, but fall out of the type system in an
important, but relatively obscure, way.  As far as I can tell, the strange
inconsistencies are the Core Working Groups best effort to steer us out of
trouble should we ever encounter such a thing in the wild, and before template
metaprogramming with generated types became a common idiom, and the
<tt>std::function</tt> proposal for Library TR1 put function types directly in
the spotlight.
</p>

<blockquote><pre>
struct host {
   int function() const;// { return 42; }
};

template &lt;typename TYPE&gt;
constexpr bool test(TYPE host::*) {
    return is_same_v&lt;TYPE, int() const&gt;;
}

constexpr auto member = &amp;host::function;

static_assert(test(member), "This is why abominations exist");
<pre></blockquote>

<p>
In this example, we want to know the type that the pointer-to-member
<tt>host::*</tt> refers to, for the member <tt>function</tt>.  The
<i>cv-</i>qualifier on the member is vital to <tt>const</tt> correct type
safety in the language.  Clearly, the compiler needs a distinct type to
represent this, and users are going to need a way to spell that type if they
are to interact using it.
</p>



<h2><a name="3.0">3 Concerns</a></h2>
<p>
The main problem causes by abominable function types occur in generic code.
Templates must document the constraints on the types that their type parmaeters
can be instantiated with, or can be assumed to accept any type.  For example,
there should be no constraints on the type parameters to <tt>is_same</tt>, as
the behavior of the type is not relevant to the result.  For a trait like
<tt>is_constructible</tt>, you need to consider whether it is reasonable to
support any type, including incomplete types (including <tt>void</tt>) or
whether to limit the types that they support.  Note that it is often reasonable
to have a trait return <tt>false</tt> for a meaningless question, such as
whether <tt>void</tt> types are copy constructible, rather than exclude them
from the supported set of types.
</p>
<p>
In many cases, the simplest option for handling abominable function types in a
trait (or other metaprogram) is simply to state that they are not supported.
The main problem here is a lack of vocabulary, and every library author (who
takes documenting their contracts seriously) will invent their own terminology
to describe these things, and often be left with the burden of educating their
users that these awkward types exist and what they are, only to explain that
they are not supported.
</p>
<p>
Once we decide to support all types in our trait (or other template), if the
implementation of the metafuction would involve forming a reference or a
pointer, we must implement an extra layer of dispatch to detect abominable
function types to handle them specially.  This was the approach adopted by the
standard library, although it still leaves the burden of documenting the result
of traits when passed types that require such special dispatch.
</p>
<p>
The final concern is that the mere existence of these types greatly complicates
the testing of templates, as rather than using a small variety of function types
to test a trait against (functions taking 0, 1, or more arguments, and maybe with
a C-style elipsis and an awkward return type), we multiply that set by 12 to
check that there is no unguarded path throguh the template forming a reference or
pointer to an arbitrary dependant type, include the type parameters themselves.
</p>


<h2><a name="4.0">4 Recommended Direction</a></h2>
<p>
There are a number of simple to not-so-simple approaches that could be taken in
the standard to simplify these problems.  Four possible directions are described
below, with a weak recommendation for both of options 2 and 4.
</p>

<h3><a name="4.1">Option 1: Remove the abominations</a></h3>
<p>
From the generic library author's perspective, this would be the ideal solution.
If the problem is removed at source, then there is no need to worry about it.
However, the example in <a href="#2.5">2.5</a> is real, and would need some new,
distinctly novel, way to express the deduced parameter type.  The problems of
these types don't go away entirely, but are more easily expressed.
</p>
<p>
This is clearly the riskiest approach, leading to some real code breakage if
the new model is a complete replacement for the old, or a period of even more
confusion of both facilities live side-by-side during a period of deprecation.
The author no longer expects this option to be a success.
</p>

<h3><a name="4.2">Option 2: Abominations are not Function</a></h3>
<p>
Very similar to <a href="#4.1">Option 1</a>, but rather than invent a new
syntax we retain the existing form, but state that <i>function-like</i> types
that appear syntactically like a function with a <i>cv-</i>qualifier are, in
fact, not function types at all.
</p>
This option resolves the worst parts of the issue, which is that in generic
code I do not have the simple guarantee that I can form a pointer to an
arbitrary function type, nor form a reference to such a type.  This simplifies
the burden on documenters of generic type manipulation libraries, and makes
life simpler for their customers as disparate libraries each find their own
distinct way to describe abominations that might not be supportd.
<p>
</p>
<p>
Note that making this change in Core would have implications on the existing
library documentation for traits like <tt>is_function</tt>.  If abominations
cease to be functions, then the majority of the existing library documentation
would be valid, but the contracts would have changed meaning, generally leading
to simpler implementations, but returning different results in the kind of
corner case seen throughout this paper.
</p>

<h3><a name="4.3">Option 3: Make Abominations More Regular</a></h3>
<p>
The abominations would cease to be abominable if they were more regular.  The
two simplest changes to improve regularity would be to allow pointers and
references to such types, even though we know of no actual functions that could
be bound to such references, and the only (known) valid pointer values would be
<tt>nullptr</tt>.
</p>
<p>
This change would solve the majority of template metaprograms that fail with a
hard error, as these assumptions are typically made in non-SFAINE contexts.
</p>
<p>
This option provides no help for the implementation for <tt>is_function_v</tt>,
it remains the library implementer's responsibility to be aware of all the dark
corners of the type system, and handle them appropriately.
</p>

<h3><a name="4.4">Option 4: Minimal Library Cleanup</a></h3>
<p>
This is <a href="#4.2">Option 2</a>, but applied entirely in the library.  The
main drawback compared to <a href="#4.2">Option 2</a> is that the core and
library clauses either use different terms to describe the same things, or use
the same terms to mean different things.
</p>
<p>
The process to clean up the library started with
<a href=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3688.html#2196>LWG #2196</a>
which was resolved for C++14 at the Bristol meeting.  However, there is no
<tt>is_referenceable</tt> trait (nor a corresponding <tt>is_pointable</tt>)
despite the term being used as part of the precondition to a number of
traits in the library, potentially making it tricky for users to correctly
forward types in generic some generic code.
</p>
<p>
Other concerns include more clearly defining the behavior of
<tt>add_lvalue_reference_t&lt;int() const&gt;</tt>, which is currently an alias
to an invalid type (and so, presumably, should be a hard error in user code)
unlike <tt>add_lvalue_reference_t&lt;void&gt;</tt>, which is an alias back to
<tt>void</tt>.  The precondition should be more clearly spelled out, or going
with <a href="#4.2">Option 2</a> above, would immediately become well defined
behavior to return the same type, as per <tt>void</tt>.  (If it is intended
that it should be an error to invoke <tt>add_lvalue_reference_t</tt> on such
types, it should be clearly stated as a precondition, as is done for other
standard type traits, or at the very least acknowledged in a note as likely to
fail.)
</p>

<h3><a name="4.4">Option 4: Embrace in the Library</a></h3>
<p>
This option extends, <a href="#4.4">Option 4</a>, and could equally be
an extension to each of the preceding options.  The standard library,
in particular the type traits component, should be extended to properly
recognise and manipulate this vocabulary of types.
</p>
<p>
In addition to adding <tt>is_referenceable</tt> and <tt>is_pointable</tt>,
and fixing inconsistencies with <tt>add_const</tt> and <tt>add_pointer</tt>,
add the following list of traits for manipulating the <i>cv-ref</i> qualifier
on function types:
</p>
<ul>
  <li><tt>has_member_qualifiers</tt></li>
  <li><tt>is_const_member</tt></li>
  <li><tt>is_volatile_member</tt></li>
  <li><tt>is_cv_member</tt></li>
  <li><tt>is_lvalue_reference_member</tt></li>
  <li><tt>is_rvalue_reference_member</tt></li>
  <li><tt>add_member_const</tt></li>
  <li><tt>add_member_volatile</tt></li>
  <li><tt>add_member_cv</tt></li>
  <li><tt>add_member_lvalue_reference</tt></li>
  <li><tt>add_member_rvalue_reference</tt></li>
  <li><tt>remove_member_const</tt></li>
  <li><tt>remove_member_volatile</tt></li>
  <li><tt>remove_member_cv</tt></li>
  <li><tt>remove_member_lvalue_reference</tt></li>
  <li><tt>remove_member_rvalue_reference</tt></li>
  <li><tt>remove_all_member_qualifiers</tt></li>
</ul>
<p>
Note that the traits adding and removing <i>cv-</i> qualifiers are peers of
the traits adding and removing reference qualiers, unlike the regualar traits
for adding and removing <i>cv-</i> qualifiers from types, which have no effect
on reference types.
</p>
<p>
Some obvious issues with this proposal are deferred until LEWG feedback
recommends taking this direction.  For example, it is not clear whether the
following should be supported, or what it should mean:
</p>

<blockquote><pre>
using result = add_lvalue_member_reference_t&lt;void() &amp;&amp;&gt;;
<pre></blockquote>

<p>
Similarly, how should these metafunctions be interpreted when passed a
non-function type.  Should they return the type unmodified, such as
<tt>add_reference_t&lt;void&gt;</tt>, or should we consider the general case of
how these would be affected through pointer-to-member types, where adding or
removing <i>cv-</i> qualification from the dereferenced <tt>this</tt> pointer
would be similar to adding or removing the  <i>cv-</i> qualifier on the type of
the data member? 
</p>

<p>
These missing traits might also be just one aspect of a more complete type
manipulation facility for function types, which would be useful for
compile-time reflection.
</p>


</body>
</html>
