<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3153: Common and common_type have too little in common</title>
<meta property="og:title" content="Issue 3153: Common and common_type have too little in common">
<meta property="og:description" content="C++ library issue. Status: C++20">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3153.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++20">C++20</a> status.</em></p>
<h3 id="3153"><a href="lwg-defects.html#3153">3153</a>. <code>Common</code> and <code>common_type</code> have too little in common</h3>
<p><b>Section:</b> 18.4.6 <a href="https://wg21.link/concept.common">[concept.common]</a> <b>Status:</b> <a href="lwg-active.html#C++20">C++20</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2018-08-10 <b>Last modified:</b> 2021-02-25</p>
<p><b>Priority: </b>0
</p>
<p><b>View all other</b> <a href="lwg-index.html#concept.common">issues</a> in [concept.common].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++20">C++20</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The <code>Common</code> concept when applied to types <code>T</code> and <code>U</code>
requires that <code>T</code> and <code>U</code> are each <code>ConvertibleTo</code>
( [concept.convertibleto]) their common type
<code>common_type_t&lt;T, U&gt;</code>. <code>ConvertibleTo</code> requires both
implicit and explicit conversions with equivalent results. The requirement for
implicit conversion is notably not a requirement for specializing
<code>common_type</code> as detailed in 21.3.9.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a>:
</p>
<blockquote>
-5- Such a specialization need not have a member named <code>type</code>, but if it
does, that member shall be a <i>typedef-name</i> for an accessible and
unambiguous cv-unqualified non-reference type <code>C</code> to which each of the
types <code>T1</code> and <code>T2</code> is explicitly convertible.
</blockquote>
<p>
which only requires <em>explicit</em> conversion to be valid. While it's not
inconsistent that the <code>Common</code> concept's requirements are a refinement of
the requirements for <code>common_type</code>, there's no good reason for this
additional requirement. The stated design intent is to enable writing monomorphic
predicates that can compare <code>T</code>s with <code>U</code>s (and vice versa) by
accepting two arguments of type <code>common_type_t&lt;T, U&gt;</code>, but this
role has been superseded by the addition of <code>CommonReference</code> and
<code>common_reference_t</code> to the ranges design. The existence of pairs of
types that are only explicitly convertible to their common type suggests that
using <code>Common</code> in this way would never be a fully generic solution in any
case.
</p>
<p>
The only existing use of the <code>Common</code> concept in
either the working draft or the Ranges proposal is as a soundness check on the
<a href="https://timsong-cpp.github.io/cppwp/ranges-ts/counted.iter.op.comp">comparison</a>
and
<a href="https://timsong-cpp.github.io/cppwp/ranges-ts/counted.iter.nonmember">difference</a>
operators of <code>counted_iterator</code>, none of which actually convert any
argument to the common type in their normal operation. It would seem that we
could strike the additional requirement without impacting the Ranges design,
which would allow for future uses of the <code>Common</code> concept with types
like <code>chrono::duration</code> (30.5 <a href="https://wg21.link/time.duration">[time.duration]</a>) which sometimes
provide only explicit conversion to a common type.
</p>
<p>
Notably, removing the requirement for implicit conversion will also make the
<code>Common</code> concept consistent with the description in
18.4.6 <a href="https://wg21.link/concept.common">[concept.common]</a> p1: "If <code>T</code> and <code>U</code> can both be
explicitly converted to some third type, <code>C</code>, then <code>T</code> and
<code>U</code> share a common type, <code>C</code>."
</p>
<p><i>[2018-08 Batavia Monday issue prioritization]</i></p>

<p>P0; Status to 'Tentatively Ready' after adding two semicolons to the P/R.</p>
<p><i>[2018-11, Adopted in San Diego]</i></p>



<p id="res-3153"><b>Proposed resolution:</b></p>

<p>This wording is relative to <a href="https://wg21.link/n4762">N4762</a>.</p>

<ol>
<li><p>Modify the definition of <code>Common</code> in 18.4.6 <a href="https://wg21.link/concept.common">[concept.common]</a>
as follows:</p>
<blockquote>
<pre>
template&lt;class T, class U&gt;
  concept Common =
    Same&lt;common_type_t&lt;T, U&gt;, common_type_t&lt;U, T&gt;&gt; &amp;&amp;
    <del>ConvertibleTo&lt;T, common_type_t&lt;T, U&gt;&gt; &amp;&amp;</del>
    <del>ConvertibleTo&lt;U, common_type_t&lt;T, U&gt;&gt; &amp;&amp;</del>
    <ins>requires {</ins>
      <ins>static_cast&lt;common_type_t&lt;T, U&gt;&gt;(declval&lt;T&gt;());</ins>
      <ins>static_cast&lt;common_type_t&lt;T, U&gt;&gt;(declval&lt;U&gt;());</ins>
    <ins>} &amp;&amp;</ins>
    CommonReference&lt;
      add_lvalue_reference_t&lt;const T&gt;,
      add_lvalue_reference_t&lt;const U&gt;&gt; &amp;&amp;
    CommonReference&lt;
      add_lvalue_reference_t&lt;common_type_t&lt;T, U&gt;&gt;,
      common_reference_t&lt;
        add_lvalue_reference_t&lt;const T&gt;,
        add_lvalue_reference_t&lt;const U&gt;&gt;&gt;;
</pre>
</blockquote>
</li>
</ol>





</body>
</html>
