C ++ template class behaves differently for different compilers

I work with templates in C ++. Is there a difference in the use of templates and the class of friends when compiling with the MSVC compiler and when using the Mingw gcc compiler. My code compiles successfully and gives the desired result when compiling with MSVC, but it gives an error when compiling with gcc. Below is my code,

///////////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 /////////////////////////////////////////////////////////////////////////////////////// 

When compiling the above code with MSVC gives the desired result, but when compiling with the Mingw GCC compiler, it gives the following error:

 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 

What could be a possible solution to this problem? Thanks in advance.

+7
c ++ qt visual-studio-2010 templates mingw32
source share
2 answers

MSVC does not search for a two-phase name correctly. GCC reports this error correctly.

The reason is that the names used inside the template, which are independent of the template parameters (should be in the case of VC), looked up when the template was defined, and not when it was created.

In your case, the compiler cannot say that IsNonValid will be from the base class, so he rightly complains that he does not know this. There are two possible solutions:

  • IsNonValid access to IsNonValid so that it is cleared of the compiler, which it (potentially) depends on the template parameters:

     QString val = this->IsNonValid() ? "Non" : ""; // or QString val = TYPE_LIST::IsNonValid() ? "Non" : ""; 
  • Enter the inherited name in the scope of the derived class:

     template <class TYPE_LIST> class Data : public TYPE_LIST { public: using TYPE_LIST::IsNonValid; // the rest as you had it originally 

Any of them will depend on the name and, therefore, defer its search until the value TYPE_LIST is determined.

+10
source share

gcc is correct. You need to add this-> to delay the search until the instance is created.

this->IsNonValid();

MSVC does not agree with the fact that it delays all search queries until the instance is created, since it does not correctly search for two-phase names.

+7
source share

All Articles