2012-01-02 136 views
2

C++被认为是静态类型的。我明白那个。模板:静态类型还是动态?

我不明白这是如何适用于模板。

这里是不能在编译时确定一个类型的一个简单的例子:

template <typename... t> 
struct foo { 
    using type = typename foo<t..., t...>::type; 
}; 

foo<int>::type x; // type of x cannot be determined without running meta-program 

我相信存在这样的情况是不可能的检测类型错误不解决停机问题。

所以我的问题是,为什么不考虑动态类型的模板?

+0

有没有元程序运行,只是一些类型实例,所有发生在C++程序的**编译时**。 – Xeo 2012-01-02 03:01:59

+0

@Xeo它不能实例化任何东西,因为它不能确定类型 – Pubby 2012-01-02 03:03:49

+2

我假设编译器仍然会在编译时间中试图找出这种类型。任何证明违背这一假设? – 2012-01-02 03:04:20

回答

7

静态/动态类型通常是指最终编译程序运行时的行为,而不是元程序的行为。由于foo<int>::type在达到最终编译程序的运行时间时已解决,因此它被认为是静态类型。

至于模板元程序,可以认为它是使用鸭子打字,这是一种动态打字。但是,请注意,仍然存在静态类型(在C++ 11之前版本中) - 模板上的模板参数数量可以被视为元函数的元类型,用于生成具体类型(这是一个值就元程序而言)。

通过比较,在Haskell中,他们有一个层次类型的概念。你有典型的类型 - 像函数,整数等等。然后你有'种类',它描述类型的类型和元函数。例如,Haskell种类* -> * -> *可以指键到值的映射,很像C++中的template<typename Key, typename Value> class Map。任何关于语言是静态还是动态输入的决定都必须引用您所指的层次结构的哪一层。从历史上看,C++模板在初次设计时从未真正被认为是元程序,所以这类术语在C++中没有被广泛使用,但仍然可以应用相同的概念。

+0

我不明白元程序是如何动态输入的。模板使用结构化类型,这是一种静态类型。 – 2012-01-02 03:26:04

+0

@ R.MartinhoFernandes,当您引用与模板参数相关的类型时,动态类型会发挥作用。例如'std :: vector '其中'T'是模板参数;编译器必须验证存在“T :: foo”,是一种类型,并且如果是适当的类型,动态地(即在执行模板元程序时,而不是在执行模板元程序之前) – bdonlan 2012-01-02 03:29:40

+0

否, 'T :: foo'是一个值,而不是一个类型。这就是为什么你需要'typename'作为消歧器:知道没有实例化(即运行元程序)。 – 2012-01-02 03:31:59