Следующий код компилируется, но не будет работать:
template<typename T>
struct Nesting
{
template<typename U>
struct _Nested
{
};
template<typename U>
using Nested = _Nested<U>;
};
template<typename T>
struct F
{
static constexpr bool is_my_nested_class = false;
};
template<typename T, typename U>
struct F<typename Nesting<T>::Nested<U>>
{
static constexpr bool is_my_nested_class = true;
};
Я создаю эти Nesting и Nested типы и пытаюсь использовать в них образец типа. Компилируется (используя MSVC 2014 с CPP11), но
F<Nesting<int>::Nested<long>>::is_my_nested_class
возвращается ложный.
Это запрещено или не определено стандартом? Какое правило это нарушает? Любое решение?
Большое спасибо!
Ваш вложенный псевдоним может относиться к любому типу, особенно в специализации:
template<typename T>
struct Nesting
{
template<typename U>
struct _Nested
{
};
template<typename U>
using Nested = _Nested<U>;
};
// Consider this specialisation:
template<>
struct Nesting<int>
{
template<typename U>
using Nested = float;
};
Теперь понятно F<Nesting<int>::Nested<int>>::is_my_nested_class
должен быть таким же, как F<float>::is_my_nested_class
Однако, как компилятор может сделать это для последнего случая? То есть если бы я написал:
static_assert(F<float>::is_my_nested_class, "not nested");
Компилятор должен видеть, что F<float>
такой же как F<Nesting<int>::Nested<int>>
хотя последний не был создан. Поскольку этого нельзя разумно ожидать, дело не разрешено.
Других решений пока нет …