<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - Extracting the template template of a type and placing it into a template template holder fails"
   href="https://bugs.llvm.org/show_bug.cgi?id=34414">34414</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Extracting the template template of a type and placing it into a template template holder fails
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>4.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>release blocker
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>C++
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>paul@preney.ca
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=19075" name="attach_19075" title="C++98/11/14 code demonstrating the clang++ v4.0 issue.">attachment 19075</a> <a href="attachment.cgi?id=19075&action=edit" title="C++98/11/14 code demonstrating the clang++ v4.0 issue.">[details]</a></span>
C++98/11/14 code demonstrating the clang++ v4.0 issue.

The following C++ code compiles with clang++ v3.9 and earlier but not with
v4.0:

// Define a type to hold a constant value...
template <typename T, T Value>
struct value { };

// Define a type to hold a template template to a constant value...
template <template <typename T, T> class TT>
struct param_value_tt { };

// Define a type to compute the template template of a type
// that holds a constant value (e.g., value<int,2>,
// std::integral_constant<int,2>, etc.)...
template <typename T>
struct extract_param_value_tt;

template <
  template <typename T, T> class TT,
  typename U,
  U uValue
>
struct extract_param_value_tt< TT<U,uValue> >
{
  // Either typedef or using can be used here...
  typedef param_value_tt<TT> type;
};

int main()
{
  // Either typedef or using can be used here...
  typedef typename extract_param_value_tt< value<int,2> >::type holder;
}

---

With clang++ v4.0, the code fails with:

$ clang++-4.0 -Wall -Wextra -pedantic clang4-template-template.cxx
clang4-template-template.cxx:18:26: error: template template argument has
different template parameters than its
      corresponding template template parameter
  typedef param_value_tt<TT> type;
                         ^
clang4-template-template.cxx:11:26: note: template non-type parameter has a
different type 'T' in template argument
  template <typename T, T> class TT,
                         ^
clang4-template-template.cxx:4:34: note: previous non-type template parameter
with type 'T' is here
template <template <typename T, T> class TT>
                                 ^
1 error generated.

I have not tried compiling with clang++ v5 as I don't have it installed.

---

The aim of the code is to obtain the "template template" for a type and "hold"
it in a type (i.e., param_value_tt) for subsequent processing. 

In the example, if one eliminates the use of TT in extract_param_value_tt and
replaces such with specific type names (e.g., "value" and/or
"std::integral_constant") the code will compile, however, when TT is used it
fails, hence this bug report.

i.e., the following C++11 (for std::integral_constant) code shows this:

#include <type_traits>

template <typename T, T Value>
struct value { };

// NOTE: Added apply<class T, T> to apply parameters to TT...
template <template <typename T, T> class TT>
struct param_value_tt
{
  template <typename U, U uValue>
  using apply = TT<U,uValue>;
};

template <typename T>
struct extract_param_value_tt;

// Partial specializations are now specific types...
template <typename U, U uValue>
struct extract_param_value_tt< value<U,uValue> >
{
  using type = param_value_tt<value>;
};

template <typename U, U uValue>
struct extract_param_value_tt< std::integral_constant<U,uValue> >
{
  using type = param_value_tt<std::integral_constant>;
};

int main()
{
  // Code showing everything including application...
  using holder1 = typename extract_param_value_tt< value<int,2>>::type;
  using holder1_apply = typename holder1::template apply<char,'4'>;

  using holder2 = typename extract_param_value_tt<
std::integral_constant<short,2>>::type;
  using holder2_apply = typename holder2::template apply<long,5L>;
}

Paul</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>