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