Jer*_*fin 19
回过头来,"编译时多态"意味着函数重载.它仅适用于函数,因为它们都可以超载.
在当前的C++中,模板会改变它.Neil Butterworth已经举了一个例子.另一个使用模板专业化.例如:
#include <iostream>
#include <string>
template <class T>
struct my_template {
T foo;
my_template() : foo(T()) {}
};
template <>
struct my_template<int> {
enum { foo = 42 };
};
int main() {
my_template<int> x;
my_template<long> y;
my_template<std::string> z;
std::cout << x.foo << "\n";
std::cout << y.foo << "\n";
std::cout << "\"" << z.foo << "\"";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这应该产生42,0和""(一个空字符串) - 我们得到的结构对每种类型的行为都不同.
这里我们有类的"编译时多态"而不是函数.我想如果你想争论这一点,你可以声称这至少部分是构造函数(一个函数)至少在一种情况下的结果,但是专门的版本my_template甚至没有构造函数.
编辑:至于为什么这是多态.我把"编译时多态"放在引号中是有原因的 - 它与普通的多态有些不同.尽管如此,我们得到的效果类似于我们对重载函数的期望:
int value(int x) { return 0; }
long value(long x) { return 42; }
std::cout << value(1);
std::cout << value(1L);
Run Code Online (Sandbox Code Playgroud)
函数重载和特化给出了类似的效果.我同意,对于"多态"是否也适用于某些问题是开放的,但我认为它同样适用于另一个.
And*_*nck 13
使用编译时多态性通常意味着您可以拥有多个具有相同名称的函数,编译器将在编译时选择使用哪个函数,具体取决于参数:
void foo(int x);
void foo(float y);
//Somewhere else
int x = 3;
foo(x); //Will call first function
float y = 2;
foo(y); //Will call second function
Run Code Online (Sandbox Code Playgroud)
该功能foo据说是超载的.各种类型的模板实例化也可以称为编译时多态性.
小智 6
编译时多态是指C++模板编程的术语.例如,在编译时,您可以通过它包含的内容确定std :: vector的实际类型:
std::vector <int> vi;
std::vector <std::string> vs;
Run Code Online (Sandbox Code Playgroud)
我不确定你为什么认为这仅限于功能.
仅适用于函数的是模板参数推导.如果我有一个功能模板:
template <typename T>
void foo(T &t);
Run Code Online (Sandbox Code Playgroud)
然后我就能做到int a = 0; foo(a);,这相当于int a = 0; foo<int>(a);.编译器就是我的意思foo<int>.至少,它应该使用foo<int>- 如果这不是我的意思,那么运气不好,我可以写foo<unsigned int>(a);或其他什么.
但是,如果我有一个类模板:
template <typename T>
struct Foo {
T &t;
Foo(T &t) : t(t) {}
T &getT() { return t; }
};
Run Code Online (Sandbox Code Playgroud)
然后我做不到int a = 0; Foo(a).getT();.我必须指明Foo<int>(a).不允许编译器解析我的意思Foo<int>.
所以你可能会说类模板比函数模板"更少多态".多态通常意味着您不必编写代码来使对象的类型显式化.函数模板允许(在这种特定情况下),而类模板则不允许.
至于为什么会这样 - 标准是这样说的,我不知道为什么.通常的嫌疑人是:(a)实施起来太难了,(b)标准委员会认为没有用,或者(c)它在语言的其他地方造成了一些矛盾或含糊之处.
但你仍然可以用类做其他类型的多态:
template <typename T>
struct Foo {
T &t;
Foo(T &t): t(t) {}
void handleMany(int *ra, size_t s) {
for (size_t i = 0; i < s; ++i) {
t.handleOne(ra[i]);
}
}
};
Run Code Online (Sandbox Code Playgroud)
这通常也称为编译时多态,因为就模板的作者而言,t.handleOne可能是任何东西,并且在必要时它将被解析,在Foo被实例化时在编译中"稍后".
| 归档时间: |
|
| 查看次数: |
21533 次 |
| 最近记录: |