I am working with templates in C++. Is there any difference in using templates and friend class when compiled with MSVC compiler and when using Mingw gcc compiler. My code successfully compiles and gives the desired output when compiled with MSVC but it gives error when compiled 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 compiled the above code with MSVC gives desired output but when compiled with Mingw GCC compiler it gives 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 the possible solution to this problem? Thanks in advance.
Can get complicated quickly if one isn't careful. Most compilers give cryptic error messages. It can be difficult to use/debug highly templated code. Have at least one syntactic quirk ( the >> operator can interfere with templates)
In general, yes, template classes are usually compiled every time they're encountered by the compiler.
In other words, a template is a mechanism that allows a programmer to use types as parameters for a class or a function. The compiler then generates a specific class or function when we later provide specific types as arguments.
C++ template is also known as generic functions or classes which is a very powerful feature in C++. A keyword “template” in c++ is used for the template's syntax and angled bracket in a parameter (t), which defines the data type variable.
MSVC does not implement two-phase name lookup correctly. GCC is correct in reporting this error.
The cause is that names used inside a template which do not depend on the template's parameters are (should be in the case of VC) looked up when the template is defined, not when it's instantiated.
In your case, the compiler has no way of telling that IsNonValid
will come from the base class, so it rightfully complains it doesn't know it. There are two possible solutions:
Qualify the access to IsNonValid
, so that it's clear to the compiler it (potentially) depends on the template parameters:
QString val = this->IsNonValid() ? "Non" : "";
// or
QString val = TYPE_LIST::IsNonValid() ? "Non" : "";
Introduce the inherited name into 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
Either of these will make the name dependent and thus postpone its lookup until instnatiation, when the value of TYPE_LIST
is actually known.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With