lz96 lz96 - 14 days ago 6
C++ Question

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?

Answer

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.)