Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;编译器不会检查模板类中是否存在方法_C++_Templates_Definition Checking - Fatal编程技术网

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(); }
};