C ++编译器不检查模板类中是否存在方法

ves*_*sii 9 c++ templates

我在中遇到了以下程序C++

template <class T>
class Val {
protected:
    T x0, x;
public:
    Val(T t = 1) : x0(t), x(1) {}
    T val() { return x; }
    void promote() { this->promote_value(); }
};
Run Code Online (Sandbox Code Playgroud)

由于某种原因,Val<int>(4).val();即使没有方法,也可以正常工作promote_value()。我试图删除模板:

class OtherVal {
protected:
    int x0, x;
public:
    OtherVal (int t = 1) : x0(t), x(1) {}
    int val() { return x; }
    void promote() { this->promote_value(); }
};
Run Code Online (Sandbox Code Playgroud)

但是现在我得到一个错误:

错误:“类OtherVal”没有名为“ promote_value”的成员;你是说“促进”吗?

为什么会这样C++表现?

r3m*_*n0x 12

模板类方法在使用之前不会实例化。一旦您尝试致电promote()甚至获得这样的地址&Val<int>::promote,就会收到错误消息。

从C ++标准:

第17.8.1.10节,实现不得隐式实例化函数模板,变量模板,成员模板,非虚拟成员函数,成员类,类模板的静态数据成员或constexpr if语句的子语句(9.4.1),除非需要此类实例化。


Bat*_*eba 8

模板始终以这种方式工作,主要是为了促进其使用。

因为Val<int>(4).val();没有调用 promote,所以不会针对您对该模板的特定实例进行编译,因此编译器不会发出诊断信息。

许多元编程技术都依赖于这种行为。