<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<style type="text/css">/*<![CDATA[*/

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.5empadding-right: 0.5em; ; }

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

blockquote pre em { font-family: normal }

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>Standard Library Support for Void</title>
</head>
<body>

<p style="text-align: right; float: right">
ISO/IEC JTC1 SC22 WG21<br>
Document Number: P0242R0<br>
Audience: Library Evolution Working Group<br>
Matt Calabrese (<a href="mailto:metaprogrammingtheworld@gmail.com">metaprogrammingtheworld@gmail.com</a>)<br>
2016-02-11<br>
</p>

<h1>Standard Library Support for Void</h1>

<h2><a id="Abstract">Abstract</a></h2>
<p>This paper assumes the updated <code>void</code> type described in P0146R1<sup><a href="#References_RegularVoid">1</a></sup> and provides operator overloads for standard input and output with <code>void</code> such that generic code which deals with input and output will be compatible with <code>void</code> types. In addition to that, it also declares a specialization of <code>std::hash</code> for <code>void</code>.</p>

<h2><a id="Motivation">Motivation</a></h2>

<p>With the updated <code>void</code> type described in P0146R1<sup><a href="#References_RegularVoid">1</a></sup>, <code>void</code> may be instantiated and used as an object. Because of this, users may expect the standard library to support the type in similar ways that it does for many other built-in types, such as arithmetic types. One place where support may be desirable is with iostreams, allowing an instance of <code>void</code> to be input or output without users having to explicitly provide their own operator overloads. The desire for such support can come up in generic code that outputs the result of a function call using a standard output stream, for example. It would be useful if such generic code would work with <code>void</code> return types, and without users having to handle the type in a special manner. Similar concerns come up regarding function templates that hash the value of a dependent type.</p>

<h2><a id="Alternatives">Alternatives</a></h2>

<h3><a id="UndeclaredIO">Undeclared Insertion and Extraction for <code>void</code></a></h3>

<p>An alternative to providing operator overloads for insertion and extraction of <code>void</code> could be to simply leave these operators undeclared in the standard, allowing users to define their own, if needed. This has some problems:</p>

<p>
</p><ul>
<li>The need for developers to do this is inconsistent with many other built-in types.</li>
<li>If multiple projects (i.e. libraries) declare their own overloads for <code>void</code>, they will encounter multiple definitions or ODR violations when used in the same project.</li>
<li>In practice, users would have to put the overloads in the global namespace in order for them to be found from other namespaces, and those declarations would have to appear before the definition of any generic code that uses them, even if the template is instantiated after the overload is introduced, which is a very subtle detail for developers to understand (if unclear, ADL will not find such an overload in the global namespace if it is first declared between the definition of the generic function that makes the unqualified call and its instantiation, unless a separate user-defined type brings in the global namespace, since fundamental types do not introduce ADL, nor do they necessarily bring in the global namespace as an associated namespace in the event that ADL does occur).</li>
</ul>
<p></p>

<h3><a id="NonEmptyIO">Non-Empty Input and Output for <code>void</code></a></h3>

<p>Though it is recommended that operators for input and output should be provided for <code>void</code>, what the precise behavior of those operators should be is somewhat subjective. This proposal recommends treating input and output of <code>void</code> as formatted input and output functions that effectively do nothing other than return a reference to the passed-in stream. Alternatively, it could be specified that output and input deal with a consistent string, such as "void," "{}," of "0", but this is unnecessary and introduces a cost to the input and output of <code>void</code> that does not need to exist.</p>

<h3><a id="UndeclaredHash">Undeclared <code>std::hash</code> support for <code>void</code></a></h3>

<p>An alternative to providing a <code>std::hash</code> specialization for <code>void</code> could be to leave such a specialization undeclared in the standard, allowing users to define their own, if needed. This has some problems:</p>

<p>
</p><ul>
<li>The need for developers to do this is inconsistent with many other built-in types.</li>
<li>If multiple projects (i.e. libraries) declare their own specializations for <code>void</code>, they will encounter multiple definitions or ODR violations when used in the same project.</li>
</ul>
<p></p>

<h2><a id="Proposal">Proposed Solution</a></h2>

<p>This proposal suggests adding &lt;&lt; and &gt;&gt; operator overloads for <code>std::basic_ostream</code> and <code>std::basic_istream</code> respectively, along with a declared specialization of <code>std::hash</code> for <code>void</code>.</p>

<p>Add a <code>void</code> specialization of <code>std::hash</code> to the synopsis in <b>§20.9.12 [unord.hash]</b> paragraph 1:
</p><blockquote class="stdins">
<pre>template &lt;&gt; struct hash&lt;void&gt;;</pre>
</blockquote>

<p>Add paragraphs to the end of <b>§27.7.2.2.3 [istream::extractors]</b>:
</p><blockquote class="stdins">
<pre>template&lt;class charT, class traits&gt;
basic_istream&lt;charT,traits&gt;&amp; operator&gt;&gt;(basic_istream&lt;charT,traits&gt;&amp; in,
                                        void&amp; v);
<i>Effects:</i> Behaves like a formatted input function ( 27.7.2.2.1) of in.
<i>Returns:</i> *this.
</pre>
</blockquote>

<p>Add section <b>§27.7.3.6.5 Void inserter function templates [ostream.inserters.void]</b>:
</p><blockquote class="stdins">
<pre>template&lt;class charT, class traits&gt;
  basic_ostream&lt;charT,traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;charT,traits&gt;&amp; out,
                                          void v);
<i>Effects:</i> Behaves as a formatted output function ( 27.7.3.6.1) of out.
<i>Returns:</i> *this.
</pre>
</blockquote>

<h2><a id="References">References</a></h2>
<p>[<a id="References_RegularVoid">1</a>] Matt Calabrese: "Regular Void" <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0146r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0146r1.html</a></p>

</body></html>