C++ C++;编译器不会检查模板类中是否存在方法
我在C++ C++;编译器不会检查模板类中是否存在方法,c++,templates,definition-checking,C++,Templates,Definition Checking,我在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(); } }; 但现在我得到一个错误: 错误:“类OtherVal”没有名为“promote_value”的成员;你是说“
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(); }
};
但现在我得到一个错误:
错误:“类OtherVal”没有名为“promote_value”的成员;你是说“提升”吗
为什么
C++
的行为是这样的?模板类方法在使用之前不会被实例化。一旦您尝试调用promote()
,甚至像这样得到它的地址&Val::promote
,您就会得到一个错误
<>从C++标准:
§17.8.1.10实现不得隐式实例化功能
模板、变量模板、成员模板、非虚拟成员
函数、成员类、类模板的静态数据成员,
或constexpr if语句(9.4.1)的子语句,除非
需要实例化
模板总是以这种方式工作,主要是为了方便使用 因为
Val(4.Val()
不调用promote
,该函数未针对该模板的特定实例化进行编译,因此编译器不会发出诊断
许多元编程技术都依赖于这种行为。谢谢。编译器是否对
promote()
执行任何检查?我猜是语法错误。@vesil,AFAIK编译器有义务按照标准解析非实例化的方法定义,并在不知道T
的情况下尽可能多地检查其正确性。然而,众所周知,MSVC违反了这一要求,不费心检查任何东西,因此允许方法定义中完全没有意义,只有在实际使用该方法时才会发现。因此,如果方法promote()
是虚拟的,则编译会失败?@vesii,是的,实际上会,因为使其虚拟将使编译器隐式获取其地址,以便将其放入虚拟表中。
class OtherVal {
protected:
int x0, x;
public:
OtherVal (int t = 1) : x0(t), x(1) {}
int val() { return x; }
void promote() { this->promote_value(); }
};