C ++模板只是“语法安全”而不是先安全类型?

时间:2013-12-17 19:01:15

标签: c++ templates types language-lawyer

至少检查两次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;
}

3 个答案:

答案 0 :(得分:3)

模板是模板。

类型是一种类型。

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

模板和类型具有名称。必须声明和定义作为联合和类的类型才能完成。必须声明模板,并定义模板以便专门化。

这就是我所能想到的,这应该是足够的词汇来讨论C ++类型系统的大多数方面的“初稿”级别。

答案 1 :(得分:2)

将C ++模板视为类固醇上的宏并具有语法知识。 离。

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

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

答案 2 :(得分:1)

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

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

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