C++模板类对于不同的编译器的行为不同
C++ template class behaves differently for different compilers
我正在使用C++模板。使用 MSVC 编译器编译和使用 Mingw gcc 编译器时,使用模板和友元类有什么区别吗?我的代码在使用 MSVC 编译时成功编译并给出所需的输出,但在使用 gcc 编译时会出错。下面是我的代码,
///////////Record.h/////////////////////
#include "Base.h"
class Derived1;
class Derived2;
template <class TYPE_LIST> class List;
class FRecord
{
public:
FRecord();
virtual ~FRecord();
friend class Base;
#if _MSC_VER <= 1200
friend class List<Derived1>;
friend class List<Derived2>;
#else
template <class TYPE_LIST> friend class List;
#endif
};
///////////////////////////////////////////////////////////////
///////////////////Base.h/////////////////////////////////
class Base
{
public:
Base(const HEADER *hc, const FRecord *fr);
virtual ~Base();
__inline bool IsNonValid() const;
protected:
quint32 Size;
};
/////////////////////////////////////
// Data
/////////////////////////////////////
template <class TYPE_LIST>
class Data : public TYPE_LIST
{
public:
Data(const HEADER *hc, const FRecord *fr) : TYPE_LIST(hc, fr)
{
QString val = IsNonValid() ? "Non" : "";
LOG0("Data ("<< val << " Valid)");
}
virtual ~Data()
{
LOG0("Data deleted");
}
}; // Data
///////////////////////////////////////////////////////////////////////////////////////
当使用 MSVC 编译上述代码时,会给出所需的输出,但当使用 Mingw GCC 编译器编译时,它会给出以下错误,
Base.h:1154: error: there are no arguments to 'IsNonValid' that depend on a template parameter, so a declaration of 'IsNonValid' must be available
Base.h:1553: error: 'Size' was not declared in this scope
这个问题的可能解决方案是什么?提前谢谢。
MSVC 没有正确实现两阶段名称查找。GCC 报告此错误是正确的。
原因是模板内使用的名称不依赖于模板的参数(应该在 VC 的情况下(在定义模板时查找,而不是在实例化时查找。
在您的情况下,编译器无法判断IsNonValid
将来自基类,因此它理所当然地抱怨它不知道它。有两种可能的解决方案:
-
限定对
IsNonValid
的访问,以便编译器清楚它(可能(取决于模板参数:QString val = this->IsNonValid() ? "Non" : ""; // or QString val = TYPE_LIST::IsNonValid() ? "Non" : "";
-
将继承的名称引入派生类的作用域:
template <class TYPE_LIST> class Data : public TYPE_LIST { public: using TYPE_LIST::IsNonValid; // the rest as you had it originally
其中任何一个都会使名称依赖,从而推迟其查找,直到实际知道TYPE_LIST
的值。
gcc 是正确的。您需要添加this->
以将查找延迟到实例化时间。
this->IsNonValid();
MSVC 不符合要求,因为它没有正确实现两阶段名称查找,因此它将所有查找延迟到实例化时间。
相关文章:
- 如何泛化作用于不同类型的向量的函数?
- 由于相同的文件名/类名存在于不同的SO中而导致的SEG错误
- Visual Studio 2015资源视图和资源编译器使用不同的方法在项目目录中查找图标文件.如何修复
- 通过函数传递随机引擎-为什么不同的编译器表现不同
- 如果 Constexpr 在 lambda 中,则编译器行为不同
- 编译器以不同的方式处理数学?
- GCC,Apple LLVM和MSVC编译器的不同部分的名称是什么?
- 将相同的功能应用于不同大小的N数组的每个元素
- 模板参数适用于不同的STL容器
- 用Mac OS X上的其他编译器使用不同的编译器进行建筑提升
- ARM Cortex-A8:使用简单浮点乘法时,来自交叉编译器的不同程序集输出
- (【理论】)编译器和不同的传递类型
- 编译器的不同输出
- boost::bind 似乎使用不同的编译器生成不同的符号
- 如何使用 CMake 强制 c++ 编译器使用不同已安装包的版本之一?
- 如何使此代码适用于不同计算机上的服务器和客户端
- C++编译器:为不同线程整理的接口
- 具有外部链接的编译器的不同行为
- QT5:如何将一个样式表应用于不同的小部件
- 不同的编译器使用不同的强制转换操作符