为什么可以在模板参数列表中声明类名

这个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++ 语法中的奇怪之处。


以上是为什么可以在模板参数列表中声明类名的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>