c++templateslanguage-lawyerdependent-name

C++ dependent name: Is this typename required?


In a.hpp I defined:

#include <utility>
namespace Board {
    template<int W, int H>
    struct GroupNode
    {
        using PointType = std::pair<int, int>;
        // ...
    };
}

Then, in b.cpp I defined:

#include "a.hpp"
namespace Board {
    template<int W, int H>
    struct NodeList
    {
        using StdList = std::list < /* typename */ GroupNode<W, H>>;
    }
}
// and then use NodeList<19, 19> nl;

The code above could be compiled on both gcc-6 and clang-3.9 without any warning. However, Clion 2016.3 complained cannot resolve variable GroupNode in b.cpp. Uncommenting typename could tame Clion warning, but I was wondering whether this typename is required? If so, why g++/clang++ didn't give out any warnings?


Solution

  • No, it is not required. According to [temp.res]/3 in C++14:

    When a qualified-id is intended to refer to a type that is not a member of the current instantiation (14.6.2.1) and its nested-name-specifier refers to a dependent type, it shall be prefixed by the keyword typename, forming a typename-specifier . If the qualified-id in a typename-specifier does not denote a type, the program is ill- formed.

    Here there is no nested-name-specifier referring to a dependent type, so typename is not required. (nested-name-specifier refers to a :: and the type or namespace to its left. Clearly, std is not a type, much less a dependent type.)