【问题标题】:When must a type used as template argument be complete if it is used internally in a context that requires a complete type? [duplicate]如果在需要完整类型的上下文中内部使用,用作模板参数的类型何时必须是完整的? [复制]
【发布时间】:2011-12-15 09:17:23
【问题描述】:

可能重复:
Incomplete class usage in template

我有一个问题困扰了我几个小时。

最初我认为类型在实例化点必须是完整的,但我尝试过的所有编译器都接受该类型在该点仍然不完整,只要它被定义翻译单元中的任何位置。

为了说明这一点,问题是关于这个简单程序的正确性:

template <typename T>
int size() {
   return sizeof(T);   // T is required to be complete in this expression
}
class test;            // test is declared, but incomplete

int main() {
   size<test>();
}
// [1] point of instantiation of size<test>()

class test {};         // Definition of test, now it is complete

根据 §14.6.4.1/1,size&lt;test&gt; 的实例化点是标记为 [1] 的行,此时 test 类型仍然不完整。如果我们尝试在那里执行sizeof(test) 操作,编译器将无法告诉我们类型不完整。然而调用一个模板,其中执行相同操作的类型在 g++、clang++、comeau 和 Visual Studio 2010 中编译。

前面的代码真的正确吗?如果在同一翻译单元中的任何位置complete,它在标准中的哪个位置支持将用作模板参数的类型视为complete?或者当必须完成?

【问题讨论】:

  • 非常相似的问题:stackoverflow.com/questions/7210286
  • @aschepler:我相信它们是完全一样的,唯一的区别是我投票结束。我不会(还)删除它以 bump 你的问题,看看是否有人提出了答案(你的问题的唯一答案有点偏离)。感谢您指出重复。
  • @aschepler:绝对是重复的,但是这个问题似乎越来越受到关注(生活是不公平的)。我真的很希望我们的标准制定者能来这里。

标签: c++ templates


【解决方案1】:

模板在最后展开后才被编译(此时测试完成)。

【讨论】:

  • 我同意这与那些编译器的行为一致,但我试图弄清楚这是否与标准中的规则一致。无论如何 +1。
  • 这将是 MSVC 的行为,但从标准的角度来看,我希望生成发生在实例化的第一个点。
  • @MatthieuM.:这种行为在我尝试过的所有编译器中都是一致的,所以不仅仅是 MSVC。 Alf Steinbach 在聊天中指出了翻译阶段,特别是 2.2/8,这表明模板实例化是在非模板化代码的翻译之后的阶段执行的。这仅表明 in time 实例化是在 处理完所有 TU 之后执行的,但这并不意味着 inspace 该类型确实不需要在实例化点之前完成。我已将其添加为对副本的答案。
  • @DavidRodríguez-dribeas:是的,我理解时间/上下文的差异。只是在 TU 结束时模板化代码完全实例化是 MSVC 的一个已知 bug,并且没有“记忆”上下文(甚至后来声明的非依赖函数也被考虑在内)。 ..但是让我们将讨论带到另一个问题:p
  • 好吧,你让我好奇地深入研究 gcc 源代码。我有一种感觉,扩展的模板包含文件是在第一遍时在内存中为模板生成的。哦,看,一个模板.. 将整个 tu 传递给生成虚拟模板头函数,然后继续编译这个 tu 的其余部分。实际上,通过 TU 的一条路径只关心组装一个完整的模板头。我会让你知道我看到了什么。
猜你喜欢
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
  • 1970-01-01
  • 2019-06-21
  • 1970-01-01
  • 2021-12-11
  • 2011-12-14
相关资源
最近更新 更多