<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - std::common_type<void, void> fails to compile"
   href="http://llvm.org/bugs/show_bug.cgi?id=22135">22135</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::common_type<void, void> fails to compile
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.4
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>pip88nl@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu, mclow.lists@gmail.com
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>From the description of std::common_type in the draft N4296, paragraph
20.10.7.6:

The member typedef type shall be defined as set out below. All types in the
parameter pack T shall be complete or (possibly cv) void.

Further down, it specifies the implementation of common_type as follows:

— If sizeof...(T) is greater than one, let T1, T2, and R, respectively, denote
the first, second, and (pack of) remaining types comprising T. [ Note:
sizeof...(R) may be zero. — end note ] Let C denote the type, if any, of an
unevaluated conditional expression (5.16) whose first operand is an arbitrary
value of type bool, whose second operand is an xvalue of type T1, and whose
third operand is an xvalue of type T2. If there is such a type C, the member
typedef type shall denote the same type, if any, as common_type_t<C,R...>.

The problem here is that expression of type void are never xvalues, since there
is no way to create (rvalue) references to void. This is a defect in the
standard draft not present in the C++11 standard (where the implementation is
defined in terms of declval<T>()).

I suggest specialising the libc++ implementation such that argument packs
containing only void cause the type defined within common_type to be void.

My workaround is this:

template<typename ...Types>
struct common_type;

template<typename Type1, typename Type2, typename ...Types>
struct common_type<Type1, Type2, Types...>
  : common_type<typename common_type<Type1, Type2>::type, Types...>
{ };

template<typename Type1, typename Type2>
struct common_type<Type1, Type2>
  : std::common_type<Type1, Type2>
{ };

template<>
struct common_type<void, void>
{ typedef void type; };</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>