https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70141
--- Comment #7 from Alexander Kondratskiy <kholdstare0.0 at gmail dot com> ---
To add some color, maybe this is related to non-deduced contexts from
14.8.2.5p5 in the standard:
The non-deduced contexts are:
— The nested-name-specifier of a type that was specified using a qualified-id.
So I agree that this should not work for code like the following, where the T
in outer<T> is being deduced:
template <typename T>
struct outer
{
template <typename U>
struct inner
{
};
};
// doesn't work, because non-deduced context
template <typename T, typename U>
void foo(typename outer<T>::template inner<U> val)
{ }
void bar()
{
foo(typename outer<int>::template inner<double>{});
}
But in the situation mentioned here, outer<T> is a concrete type, so anything
within it should be deducible. If I get rid of the template parameter on outer,
everything works fine, and the following code compiles:
// no outer template!
struct outer
{
template <typename U>
struct inner
{
};
};
struct is_inner_for
{
template <typename Whatever>
struct predicate
{
static constexpr bool value = false;
};
template <typename U>
struct predicate<outer::inner<U>>
{
static constexpr bool value = true;
};
};
static_assert(
is_inner_for::predicate<
outer::inner<double>
>::value,
"Yay!"
);
This simplified case where outer has no template parameter, in my mind should
not be any different from the original problem - it's just that we had a
template parameter but it was fully specified.