c++ - 是否在不提供模板参数未定义行为的情况下调用模板基类方法?
问题描述
我正在研究用 C++ 编写的多平台代码(Windows、Linux 和 Mac)。今天我不得不找到一个问题,这个问题只在windows中出现,看起来是编译器问题。具有多个基类的类调用基类方法,但传递错误的值作为 this。
我写了一个简短的 C++ 示例来重现这个问题:
#include <stdio.h>
class base1
{
public:
int x;
base1(int x):x(x)
{
printf("%s(): this=%p x=%d\n", __FUNCTION__, this, x);
}
void printx()
{
printf("%s(): this=%p x=%d\n", __FUNCTION__, this, x);
}
void print()
{
printf("%s(): this=%p\n", __FUNCTION__, this);
printx();
}
};
template <class T>
class base2
{
public:
int y;
base2(int y):y(y)
{
printf("%s(): this=%p y=%d\n", __FUNCTION__, this, y);
}
void printy()
{
printf("%s(): this=%p y=%d\n", __FUNCTION__, this, y);
}
void print()
{
printf("%s(): this=%p\n", __FUNCTION__, this);
printy();
}
};
class derived: public base1, public base2<derived>
{
public:
int z;
derived()
: base1(1)
, base2(2)
, z(3)
{
printf("%s(): this=%p z=%d\n", __FUNCTION__, this, z);
}
void printz()
{
printf("%s(): this=%p z=%d\n", __FUNCTION__, this, z);
}
void print()
{
printx();
base1::printx();
base1::print();
printf("-----\n");
printy();
base2::printy(); // <--- this call does not work with vs2005
base2::print(); // <--- and this call doesn't work, too.
base2<derived>::printy();
base2<derived>::print();
printf("-----\n");
printz();
}
};
int main(int argc, char *argv[])
{
derived d;
printf("-----\n");
d.print();
}
该代码在 Windows(使用 vs2005 和 vs2010)、Linux(g++(Gentoo 6.4.0-r1 p1.3)6.4.0)和 MacOS(Apple LLVM 版本 8.1.0(clang-802.0.42))上编译时没有任何警告.
代码应始终打印 x=1、y=2 或 z=3。
但是 vs2005 编译的可执行文件显示 y=3 用于调用 base2::printy() 和 base2::print()。
base1::base1(): this=0018FF3C x=1
base2<class derived>::base2(): this=0018FF40 y=2
derived::derived(): this=0018FF3C z=3
-----
base1::printx(): this=0018FF3C x=1
base1::printx(): this=0018FF3C x=1
base1::print(): this=0018FF3C
base1::printx(): this=0018FF3C x=1
-----
base2<class derived>::printy(): this=0018FF40 y=2
base2<class derived>::printy(): this=0018FF44 y=3 <--------
base2<class derived>::print(): this=0018FF44
base2<class derived>::printy(): this=0018FF44 y=3 <--------
base2<class derived>::printy(): this=0018FF40 y=2
base2<class derived>::print(): this=0018FF40
base2<class derived>::printy(): this=0018FF40 y=2
-----
derived::printz(): this=0018FF3C z=3
当 base2 是常规类而不是类模板时,调用按预期工作。
由于base2是类模板,所以基类的全称不是base2而是base2<derived>。但无论如何,没有编译器会抱怨缺少模板参数,但是 vs2005 会默默地生成代码,将错误的 this 指针传递给被调用的方法。
所以,这是我的问题:
这“只是”vs2005 中的编译器错误还是没有编译器抱怨的未定义行为?
解决方案
推荐阅读
- javascript - 如何制作一个按钮来隐藏一列并展开另一列?
- python - 如何订阅 django 频道休息框架中模型的所有实例?
- html - 位置粘性未正确粘贴
- php - 文件存在时调用 null Laravel 上的成员函数 move()
- javascript - 返回带有承诺的对象(解决,拒绝)
- android - 在 Android 中连接 wamp 服务器
- javascript - 即使我有这个角色,仍然会发送失败消息
- node.js - 当所有测试成功或失败时,有没有办法向 Jest 添加回调?
- php - Composer:如何将私有存储库添加为依赖项?
- python - 使表单仅显示 SelectField 中的某个值