<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; }
consistent { font-weight: bold; color: #005100; }
inconsistent { font-weight: bold; color: #CC0000; }
meh { font-weight: bold; color: #FFAA00; }

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, th, td { border: 1px solid black; }

/*]]>*/
</style>

<title>std::integral_constant with a Deduced Value Type</title>
</head>
<body>

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

<h1>std::integral_constant with a Deduced Value Type</h1>

<h2><a id="Abstract">Abstract</a></h2>
<p>Following EWG's acceptance of P0127, "Declaring non-type template arguments with auto," <sup><a href="#References_P0127">[1]</a></sup> this paper proposes a form of <code>std::integral_constant</code> that uses the new language feature such that the value type does not need to be explicitly specified by users.</p>

<h2><a id="Motivation">Motivation</a></h2>
<p>Usage of <code>std::integral_constant</code> can be redundant in that both an explicit value type needs to be specified and a value of that type. In practice, now the value type can be deduced from the value that is specified although there was no way to do this prior to the acceptance of P0127. Already, a standard alias for <code>bool</code> values has been accepted called <code>std::bool_constant</code>  <sup><a href="#References_BoolConstant">[2]</a></sup>, and Boost.MPL has long provided convenience wrappers for constants of other various buit-in types, such as <code>int_</code>, <code>char_</code>, and <code>long_</code> <sup><a href="#References_MPLNumericTypes">[3]</a></sup>. While a form of <code>std::integral_constant</code> template with a deduced value type would not completely obviate the utility of such named facilities, it would satisfy many uses of them and remove a little bit of redundancy.</p>

<h2><a id="Suggested">Suggested Specification</a></h2>
<p>There are several ways that such a facility could be provided, each with their own subtleties. The specification that is recommended here is a conservative one where <code>std::constant</code> is an alias of <code>std::integral_constant</code>:</p>

<pre style='color:#000000;background:#ffffff;'><span style='color:#800000; font-weight:bold; '>template</span> <span style='color:#800080; '>&lt;</span><span style='color:#800000; font-weight:bold; '>auto</span> V<span style='color:#800080; '>></span>
<span style='color:#800000; font-weight:bold; '>using</span> constant <span style='color:#808030; '>=</span> integral_constant<span style='color:#800080; '>&lt;</span>decltype<span style='color:#808030; '>(</span>V<span style='color:#808030; '>)</span><span style='color:#808030; '>,</span> V<span style='color:#800080; '>></span><span style='color:#800080; '>;</span>
</pre>

<p>The above definition does not change the definition of <code>std::integral_constant</code>, so existing uses of <code>std::integral_constant</code> cannot break. Because <code>std::constant</code> would be an alias of <code>std::integral_constant</code>, developers can safely use it for convenience in most places that <code>std::integral_constant</code> is required.</p>

<h2><a id="Limitations">Limitations</a></h2>
<p>This formulation of <code>std::constant</code> has a limitation. First, it cannot be used to form a <code>std::integral_constant</code> whose first argument is a reference type. This limitation could be removed by specifying <code>std::constant</code> to have a <code>decltype(auto)</code> parameter instead of an <code>auto</code> parameter, though that would make it possible for users to accidentally specify a reference. It is unclear how unfortunate this limitation may be, as use of <code>std::integral_constant</code> with reference types may be considered by many to be a misuse, and if the type were automatically deduced to be a reference type, it would likely be a programmer error anyway.</p>

<h2><a id="Alternative">Alternative Specifications</a></h2>
<p>The author of the underlying language facility has expressed that in an ideal world, he feels <code>std::constant</code> should be the primary template, with <code>std::integral_constant</code> reformulated to be an alias of <code>std::constant</code>. This option should be considered, although it does risk breaking code, such as code that uses <code>std::integral_constant</code> to create references. If this breakage is considered acceptable, then this option should be reconsidered.</p>

<h2><a id="Acknowledgments">Acknowledgments</a></h2>
<p>Thanks to James Touton for proposing the underlying language feature and for his feedback on this paper.</p>

<h2><a id="References">References</a></h2>
<p>[<a id="References_P0127">1</a>] James Touton, Mike Spertus: "Declaring non-type template arguments with auto" P0088R0 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0127r1.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0127r1.html</a></p>
<p>[<a id="References_BoolConstant">2</a>] Zhihao Yuan: "Wording for bool_constant" <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4389.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4389.html</a></p>
<p>[<a id="References_MPLNumericTypes">3</a>] Aleksey Gurtovoy and David Abrahams: "The MPL Reference Manual" <a href="http://www.boost.org/doc/libs/1_61_0/libs/mpl/doc/refmanual/numeric.html" target="_blank">http://www.boost.org/doc/libs/1_61_0/libs/mpl/doc/refmanual/numeric.html</a></p>
</body></html>
