The title is a bit confusing but what I mean is this specific case:
template<class>
struct get_type_of_nontype;
template<class T, T Value, template<T> class Template>
struct get_type_of_nontype<Template<Value>> {
using type = T;
};
So I can use it like this:
#include <type_traits>
template<int I>
class int_non_type {};
static_assert(
std::is_same<typename get_type_of_nontype<int_non_type<0>>::type, int>::value,
"T is deduced to be `int` as `template<T> class Template` is `template<int> class int_non_type`"
);
This works fine in C++17. In C++14 I get the following errors:
gcc 8:
<source>:5:8: error: template parameters not deducible in partial specialization:
struct get_type_of_nontype<Template<Value>> {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:5:8: note: 'T'
clang 7:
<source>:5:8: error: class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used [-Wunusable-partial-specialization]
struct get_type_of_nontype<Template<Value>> {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:4:16: note: non-deducible template parameter 'T'
template<class T, T Value, template<T> class Template>
^
And then they both complain that struct get_type_of_nontype<int_non_type<0>>
is incomplete, so typename get_type_of_non_type<int_non_type<0>>::type
can't compile.
Why is this different between C++14 and C++17? Is this just a compiler bug? If not, is there a way to do this in C++14?
T
is deduced fromT Value
and nottemplate <T> class
. This makes it sound like there is no way to do this at all in C++14. – Hysterectomy