c++templatesnested-types

C++ template specializations not working with nested types


The following code compiles, but will not work:

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

I create these Nesting and Nested types and try to uses a type trait pattern on it. It compiles (using MSVC 2014 w/ CPP11), but

F<Nesting<int>::Nested<long>>::is_my_nested_class

returns false.

Is this forbidden or undefined by the standard ? What rule does it break ? Any workaround ?

Thank you very much!


Solution

  • Your nested alias could refer to any type, particularly in a specialisation:

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

    Now, clearly F<Nesting<int>::Nested<int>>::is_my_nested_class should be the same as F<float>::is_my_nested_class, however, how can the compiler deduce this for the latter case? That is, if I wrote:

    static_assert(F<float>::is_my_nested_class, "not nested");
    

    The compiler would need to see that F<float> is the same as F<Nesting<int>::Nested<int>>, even though the latter hasn't been instantiated. As it can't reasonably be expected to do so, the case is disallowed.