何时执行类型检查的类型检查?

时间:2017-09-01 14:28:43

标签: c++ templates programming-languages computer-science generic-programming

这是来自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;是否在运行时完成类型检查?

感谢。

2 个答案:

答案 0 :(得分:2)

  
      
  • 时间&#34;当我们尝试使用这样的对象时#34;和
  •   
  • &#34;使用点&#34;?
  •   

两者都是指源代码,而不是运行时。

在这一行:

arbiter<string, case_sensitive> cs_names;

编译器看到std::stringcase_sensitive,并尝试实现arbiter的版本,T替换为std::stringCcase_sensitive替换。

如果您使用其他类型定义另一个arbiter,则会生成并编译新版本的arbiter

答案 1 :(得分:0)

阿兰有权利。

对于将来参考C ++,通常,编译时会检查所有内容。我所知道的唯一例外是多态类型的动态转换和函数typeid,它返回一个对象的类型。

在我看来,如果您使用这些功能,通常应该重新考虑您的O-O设计。 (或者你试图在没有重构的情况下修复其他人破坏的代码)。