编译器何时需要计算别名?



请考虑以下代码:

template <class T>
struct computation {
using type = /* something based on T that takes time to compile */;
};

现在考虑两个代码:

using x = computation<T>;

和:

using y = typename computation<T>::type;

我想知道该标准是否意味着:

  • 选项 A)任何"合理"的编译器都会导致x的快速编译时间和较长的编译时间y
  • 选项 B)即使只调用computation<T>,编译器也可以完全计算computation<T>::type,即使对于x,也会导致很长的编译时间

换句话说,我试图知道该标准是否指定了最有可能转化为"合理"编译器计时器的选项 A 或选项 B 的任何内容。我知道该标准没有提到编译器实现,但是例如,如果它要求::type在被专门调用之前不必存在,那将有利于选项A。

注意:根据我的经验,我很确定g++clang++msvcintel都遵循选项 A),但我不知道这是否只是纯粹的运气,因为它与标准中的某些内容有关。

我假设T在这里是一个实际的非依赖类型,而不是另一个模板参数。

<小时 />

生产线

using x = computation<T>;

不会导致computation<T>的隐式实例化。因此,编译器没有理由在这一点上尝试计算type,特别是因为任何实例化失败都需要忽略。如果type的计算会产生无效的类型或失败,程序可能不会编译失败。

该行

using y = computation<T>::type;

确实需要隐式实例化computation<T>因为范围解析运算符应用于它。隐式实例化包括计算computation<T>中的类型别名。编译器必须执行计算,因为如果计算失败或生成无效类型,则程序格式不正确,编译器需要对其进行诊断。

这实际上并不具体取决于::type部分。即使它::type2为另一个类型别名,类模板专用化的隐式实例化也需要计算type

类似地,在任何其他需要其完整的上下文中使用computation<T>将需要隐式实例化,因此需要计算type,例如

auto z = computation<T>{};

最新更新