C++ 相关名称:是否需要此类型名称?
C++ dependent name: Is this typename required?
在a.hpp
中我定义了:
#include <utility>
namespace Board {
template<int W, int H>
struct GroupNode
{
using PointType = std::pair<int, int>;
// ...
};
}
然后,在b.cpp
中我定义了:
#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;
上面的代码可以在 gcc-6 和 clang-3.9 上编译,没有任何警告。
然而,Clion 2016.3 在 b.cpp
中抱怨 cannot resolve variable GroupNode
。取消注释 typename
可以驯服 Clion 警告,但我想知道这个 typename
是否是必需的?如果是这样,为什么 g++/clang++ 没有发出任何警告?
不,不需要。根据 C++14 中的 [temp.res]/3:
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.
此处没有 nested-name-specifier 引用依赖类型,因此不需要 typename
。 (nested-name-specifier 指的是 ::
及其左侧的类型或命名空间。显然,std
不是类型,更不是依赖类型.)
在a.hpp
中我定义了:
#include <utility>
namespace Board {
template<int W, int H>
struct GroupNode
{
using PointType = std::pair<int, int>;
// ...
};
}
然后,在b.cpp
中我定义了:
#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;
上面的代码可以在 gcc-6 和 clang-3.9 上编译,没有任何警告。
然而,Clion 2016.3 在 b.cpp
中抱怨 cannot resolve variable GroupNode
。取消注释 typename
可以驯服 Clion 警告,但我想知道这个 typename
是否是必需的?如果是这样,为什么 g++/clang++ 没有发出任何警告?
不,不需要。根据 C++14 中的 [temp.res]/3:
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.
此处没有 nested-name-specifier 引用依赖类型,因此不需要 typename
。 (nested-name-specifier 指的是 ::
及其左侧的类型或命名空间。显然,std
不是类型,更不是依赖类型.)