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