为什么可以在模板参数列表中声明类名
这个Chromium 文档提供了一个奇怪的代码片段:
using ForReload = base::StrongAlias<class ForReloadTag, bool>;
^^^^^^^^^^^^^^^^^^
it compiles, though not declared anywhere
其中StrongAlias定义为(源代码):
// TagType is an empty tag class (also called "phantom type") that only serves
// the type system to differentiate between different instantiations of the
// template.
...
template <typename TagType, typename UnderlyingType>
class StrongAlias {
public:
constexpr StrongAlias() = default;
constexpr explicit StrongAlias(const UnderlyingType& v) : value_(v) {}
...
};
为什么class ForReloadTag在实例化时可以在模板参数列表中说出来StrongAlias?这是某种前向声明(但稍后没有定义)吗?
回答
由于 C++ 语法的工作方式foo,您可以说class foo:
foo f1; // valid
class foo f2; // also valid
当作用域中有该名称的变量时,这可用于消除歧义:
int foo; // variable
class foo f1; // class, not the variable.
奇怪的是,当您使用此功能时,如果该类未在任何地方声明,它会为您转发声明:
void bar(class foo* fp);
即使foo没有在任何地方声明类,这也会编译。您显然也可以将其用于模板:
template <typename T>
struct foo{};
int main() {
auto f = foo<class bar>{}; // bar isn't declared anywhere
}
它被称为详细类型说明符。你可以看到这个 CppCon talk来了解更多 C++ 语法中的奇怪之处。