【问题标题】:When is type checking for type argument performed?何时执行类型参数的类型检查?
【发布时间】:2018-02-10 15:36:19
【问题描述】:

这是 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 的新实例 每次我们声明一个对象(例如,cs_names)时,模板 不同的通用参数集。 仅当我们尝试使用此类 一个对象(例如,通过调用consider)将检查是否 参数支持所有必需的操作。

因为类型检查延迟到使用点,所以没有什么神奇的 关于chooser 类。如果我们忽略定义它,然后将其排除在外 case_sensitive 的标头,代码将 仍然可以正常编译和运行。

以下两个时间点分别是编译时还是运行时:

  • “我们尝试使用此类对象的时间”和

  • “使用点”?

“类型检查延迟到使用点”是否意味着类型检查是在运行时完成的?

谢谢。

【问题讨论】:

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


    【解决方案1】:
    • “我们尝试使用此类对象的时间”和
    • “使用点”?

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

    在这一行:

    arbiter<string, case_sensitive> cs_names;
    

    编译器看到std::stringcase_sensitive,并尝试实现arbiter 的一个版本,其中T 替换为std::stringC 替换为case_sensitive

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

    【讨论】:

      【解决方案2】:

      阿兰有这个权利。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-13
        • 2021-01-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多