C++ 编译器不检查模板中是否存在方法 class
C++ compiler does not check if a method exists in template class
我在 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(); }
};
出于某种原因 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(); }
};
但是现在我得到一个错误:
error: ‘class OtherVal’ has no member named ‘promote_value’; did you mean ‘promote’?
为什么 C++
会这样?
模板 class 方法在使用之前不会被实例化。一旦你尝试调用 promote()
或者甚至像这样 &Val<int>::promote
得到它的地址,你就会得到一个错误。
来自 C++ 标准:
§ 17.8.1.10 An implementation shall not implicitly instantiate a function
template, a variable template, a member template, a non-virtual member
function, a member class, a static data member of a class template,
or a substatement of a constexpr if statement (9.4.1), unless such
instantiation is required.
模板一直以这种方式工作,主要是为了方便使用。
因为 Val<int>(4).val();
不 调用 promote
,该函数不是针对该模板的特定实例编译的,因此编译器不会发出诊断。
许多元编程技术都依赖于此行为。
我在 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(); }
};
出于某种原因 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(); }
};
但是现在我得到一个错误:
error: ‘class OtherVal’ has no member named ‘promote_value’; did you mean ‘promote’?
为什么 C++
会这样?
模板 class 方法在使用之前不会被实例化。一旦你尝试调用 promote()
或者甚至像这样 &Val<int>::promote
得到它的地址,你就会得到一个错误。
来自 C++ 标准:
§ 17.8.1.10 An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, a static data member of a class template, or a substatement of a constexpr if statement (9.4.1), unless such instantiation is required.
模板一直以这种方式工作,主要是为了方便使用。
因为 Val<int>(4).val();
不 调用 promote
,该函数不是针对该模板的特定实例编译的,因此编译器不会发出诊断。
许多元编程技术都依赖于此行为。