这是来自Scott
的Programming Language Pragmatics的一些C ++模板代码template<typename T>
class chooser {
public:
virtual bool operator()(const T& a, const T& b) = 0;
};
template<typename T, typename C>
class arbiter {
T* best_so_far;
C comp;
public:
arbiter() { best_so_far = nullptr; }
void consider(T* t) {
if (!best_so_far || comp(*t, *best_so_far)) best_so_far = t;
}
T* best() {
return best_so_far;
}
};
class case_sensitive : chooser<string> {
public:
bool operator()(const string& a, const string& b) { return a < b; }
};
...
arbiter<string, case_sensitive> cs_names; // declare new arbiter
cs_names.consider(new string("Apple"));
cs_names.consider(new string("aardvark"));
cout << *cs_names.best() << "\n"; // prints "Apple"
C ++编译器将创建
arbiter
的新实例 每次我们用a声明一个对象(例如cs_names
)时都会使用模板 不同的通用参数集。 仅在我们尝试使用此类内容时 一个对象(例如,通过调用consider
)它将检查是否 arguments支持所有必需的操作。因为类型检查延迟到使用点,所以没有任何魔力 关于
chooser
课程。如果我们忽略了它的定义,然后把它排除在外面case_sensitive
的标题,代码会 仍然可以编译并运行。
在编译时或运行时有以下两个时间点:
时间&#34;当我们尝试使用这样的对象时#34;和
&#34;使用点&#34;?
&#34;类型检查是否延迟到使用点&#34;是否在运行时完成类型检查?
感谢。
答案 0 :(得分:2)
- 时间&#34;当我们尝试使用这样的对象时#34;和
- &#34;使用点&#34;?
两者都是指源代码,而不是运行时。
在这一行:
arbiter<string, case_sensitive> cs_names;
编译器看到std::string
和case_sensitive
,并尝试实现arbiter
的版本,T
替换为std::string
和C
由case_sensitive
替换。
如果您使用其他类型定义另一个arbiter
,则会生成并编译新版本的arbiter
。
答案 1 :(得分:0)
阿兰有权利。
对于将来参考C ++,通常,编译时会检查所有内容。我所知道的唯一例外是多态类型的动态转换和函数typeid,它返回一个对象的类型。
在我看来,如果您使用这些功能,通常应该重新考虑您的O-O设计。 (或者你试图在没有重构的情况下修复其他人破坏的代码)。