【问题标题】:A C++ template is just "grammar safe" and not type safe first?C++ 模板只是“语法安全”而不是类型安全?
【发布时间】:2013-12-17 19:01:15
【问题描述】:

C++ 模板至少检查两次。首先,在声明和定义模板时,其次是在实例化模板时。模板成功实例化后,它处于类型安全状态。我的问题是,当模板成功声明和定义时,模板所在状态的名称是什么? 如果我将宏与模板进行比较,在成功的宏“实例化”之后,代码是否是类型安全的?

#define BAR(x) return x;
                        ^
// BAR is preprocessor-grammar-safe here?

struct Bar
{
  static void bar() {}
};
  ^
// Bar is type safe at this point?

template<typename T>
void foo()
{
  T::bar();
}
 ^
// foo is C++-grammar safe at this point?

int main()
{
  foo<Bar>();
             ^
  // foo is type safe at this point?

  foo<int>();
         ^
  // foo is ill-formed here?

  BAR(0);
         ^
  // BAR is type safe at this point?

  return 0;
}

【问题讨论】:

  • 我不确定 grammar safe 是否有确切的含义,我相信您的问题的答案可能是特定于编译器的......
  • @BasileStarynkevitch 说编译器开发人员:)
  • 这是一个加载的问题。你说了很多听起来像话的东西,但实际上并没有任何意义。因此很难做出回应。
  • @Kerrek SB:对不起我的英语。我的问题是, foo 在成功声明后不是类型安全的,只有“语法安全”或“语法正确”。该州的正确名称是什么?
  • 我不相信您声称“foo 不是类型安全”的说法有任何意义。 “类型安全”并不意味着您的想法,或者至少您没有以常见的方式使用它。

标签: c++ templates types language-lawyer


【解决方案1】:

将 C++ 模板想象成一个强大的宏并具有语法知识。 例如。

template<typename T> 
void func(T t) {
  t.foo();
  ...

没有任何东西声明 T 必须有一个 foo() 函数; 这将 C++ 模板与诸如 Scala 类型参数之类的东西区分开来。 我相信较新的 C++ 版本已经为此添加了一些支持。你基本上让编译“尝试”使用 t.foo() 如果没有这样的函数它编译失败。

【讨论】:

【解决方案2】:

模板就是模板。

类型就是类型。

可以通过专门化模板来获得类型(口语中的“实例化”)。

模板和类型都有名称。必须声明和定义联合和类的类型才能完整。必须声明和定义模板才能专门化。

我能想到的就这些了,这应该足以在“初稿”级别上讨论 C++ 类型系统的大部分方面。

【讨论】:

  • 这是对的,但没有告诉我声明的模板如何类型安全以及如何才能保证类型安全。
【解决方案3】:

你只是漏掉了一点:宏处理就是文本处理(在编译之前完成)

假设预处理已生成有效代码: 可以成功声明模板。但是,实例化(定义)可能会失败。

本质上是 BAR(0);不是类型安全的(这里有点夸张)!

【讨论】:

  • 您可以将模板实例化视为一种类似宏的工具,但它在实际的 C++ 编译器中运行。
  • 模板实例化是模板定义吗?我认为声明:template void foo();定义:模板 void foo() { T::bar(); }
  • 在 BAR(0) 之后;编译成功,不处于类型安全状态?
猜你喜欢
  • 2013-07-31
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多