I have a templated class:
template <typename vtype>
class BNode
{
public:
BNode::BNode(std::vector<BPoly<vtype>>& thePolys) {if(thePolys.size()) Build(thePolys);}
BNode::BNode() {}
BPlane* mPlane=nullptr;
//And more stuff
};
When I compile, I get this error on the BPlane* mPlane=nullptr line:
error C2146: syntax error: missing ';' before identifier 'BPlane'
(Using Visual Studio 2019 compiler)
Why do I need a semicolon after my {}? If I put the semicolon there, it works. But I'm curious what the problem is because I'm worried there's some issue that will bite me later.
The following code compile without any error:
#include <vector>
class BPlane;
template <class T> class BPoly { int i; };
template <typename vtype>
class BNode
{
public:
BNode(std::vector<BPoly<vtype>> &thePolys) { if (thePolys.size()) Build(thePolys); }
BNode() {}
BPlane *mPlane = nullptr;
void Build(...) {}
//And more stuff
};
int main()
{
BNode<char> s;
}
Thus, it is impossible to guess what you have done wrong as after writing simple types for missing declaration and including vector the code compile without adding any ; after a constructor.
And I have made an instantiation in main to be sure that the class is used.
Related
I am still learning C++ hard and have now generated a circular dependency that, according to C2039: Class is not a member of Namespace may be the cause to my issue that I get a C2039 error. Can somebody help me how to cut this circle?
I have two template classes and the template class tXmlGeometry<Part> has a member function that shall declare an instance of template class tXmlStraightLine. Both are inside namespace nXml but the compiler complains that tXmlStraightLine is not member of nXml.
I have to say that I bound the tXmlGeometry.h into the tXmlStraightLine header but I get an error when I try to bind the tXmlStraightLine.h into the tXmlGeometry header at the same time. I also just tried to remove the #include nXml/tXmlGeometry from the tXmlStraightLine header to no avail.
So here's a simplified code for the tXmlGeometry template class inside namespace nXml:
namespace nXml
{
template<class Part>
class tXmlGeometry : public tXmlNode<Part>
{
public:
tXmlGeometry(Part* part);
~tXmlGeometry();
void AddStraightLine2D(const pugi::xml_node& node) {};
};
}
;
and the implementation of the AddStraightLine2D method that causes the issue:
template<class Part>
inline void nXml::tXmlGeometry<Part>::AddStraightLine2D(const pugi::xml_node& this_node)
{
nXml::tXmlStraightLine<Part> straightline_xml(this);
//do more stuff
}
Here's the simplified code for the tXmlStraightLine template class:
namespace nXml
{
template<class Part>
class tXmlStraightLine : public tXmlSegment2D<Part>
{
public:
tXmlStraightLine(tXmlGeometry<Part>* geo, const int npos);
~tXmlStraightLine();
}
;
}
;
Can somebody advice me how to avoid that circular dependency?
EDIT: I corrected an error in member function naming.
Since they're both template classes, I'd consider placing them in the same header.
In order to avoid dependency issues, you can separate the declarations and definitions. Something like this:
namespace nXml
{
// tXmlGeometry<Part> declaration
template<class Part>
class tXmlGeometry : public tXmlNode<Part>
{
public:
tXmlGeometry(Part* part);
~tXmlGeometry();
inline void AddStraightLine2D(const pugi::xml_node& this_node);
};
// tXmlStraightLine declaration
template<class Part>
class tXmlStraightLine : public tXmlSegment2D<Part>
{
public:
tXmlStraightLine(tXmlGeometry<Part>* geo, const int npos);
~tXmlStraightLine();
};
// tXmlGeometry<Part> definitions
template<class Part>
inline void nXml::tXmlGeometry<Part>::AddStraightLine2D(const pugi::xml_node& this_node)
{
nXml::tXmlStraightLine<Part> straightline_xml(this);
//do more stuff
}
}
;
I have just started with C++ Qt and I wrote the following .h file: The .cpp file contains only empty constructors and destructors.
#include <QList>
class XML_Files
{
public:
XML_Files();
~XML_Files();
protected:
QList<Myclass> m_Xmls;
};
class Myclass
{
public:
Myclass();
~Myclass();
protected:
int a;
};
but I keep getting the following errors:
error C2065: 'Myclass': undeclared identifier
error C2923: 'QList': 'Myclass' is not a valid template type argument for parameter 'T'
What do I have to do to declare a Qlist with my own data type?
You can't use the name MyClass until the compiler knows about it. Since you do not declare MyClass until after XML_Files you cannot use it's name in XML_Files.
The simplest solution here is to just change the order of the declarations and declare MyClass before XML_Files.
The easy way to fix this, is to turn the order of both classes. However there is a second solution, if this is not desired or possible:
You may declare Myclass before defining it. Then compilation will succeed.
#include <QList>
class Myclass;
class XML_Files
{
public:
XML_Files();
~XML_Files();
protected:
QList<Myclass> m_Xmls;
};
class Myclass
{
// ...
};
When we compile codes in VC, we somethings have the C4251 warnings. In my case, most of the warnings come from the fact that STL is a member of the _declspec(dllexport) class. In order to have a deep understanding of the warning, I plan to create a class that will intrigue the warning. I have tried the following cases, but no C4251 warning is given, and I was wondering whether a simple example can be given. Thanks!
The cases I have tried:
class _declspec(dllexport) ClassTest
{
public:
ExportClass<int> myexport;
ClassUse myuse;
int i;
};
Case 1:
template <typename T>
class ExportClass
{
public:
T a;
T b;
};
Case 2:
class ClassUse
{
public:
int counts;
float f_value;
std::vector<int> abc;
void get_func();
template <typename T>
T ouput_value()
{
return static_cast<T>(3);
};
template<class T>
int connected()
{
T abc;
return 3;
}
};
EDIT:
I want to make it clear that the warning will not comes from invoking STL.
You should consider MSDN in that particular case:
Compiler Warning (level 1) C4251
'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
this can happen when
// C4251.cpp
// compile with: /EHsc /MTd /W2 /c
#include <vector>
using namespace std;
class Node;
class __declspec(dllimport) VecWrapper : vector<Node *> {}; // C4251
This page gives an example of a class that gives the warning message.
See following example if you want to generate the warning message without making use of STL:
class __declspec(dllimport) Foo
{
public:
Foo();
CString m_str; // WARNING C4251 HERE
};
I have a template class:
template<class T>
class CVariable
{
//lines ommited
};
and another class:
class CLengthUnits:public CUnits
{
//lines ommited
};
but when i try to return from a function:
CVariable<CLengthUnits>** PointsOfSection(void)
{
//lines ommited
}
the compiler gives me an error:
error C2143: syntax error : missing ';' before '<'
Anyone an idea?
template<class T>
class CVariable**
{
//lines ommited
};
The asterisks don't belong there. Remove them.
EDIT: In response to OP's comment, the following program compiles just fine for me:
class CUnits {};
template<class T>
class CVariable
{
//lines ommited
};
class CLengthUnits:public CUnits
{
//lines ommited
};
CVariable<CLengthUnits>** PointsOfSection(void)
{
//lines ommited
}
I think there is something you are still not telling us.
Technique 1 -> Results in error
I have three files MyType.h, MyType.cpp & main.cpp
MyType.h
#ifndef MYTYPE_H
#define MYTYPE_H
#include<iostream>
using namespace std;
template <class T,int iMax>
class A{
T iData;
public:
void vSetData(T iPar1);
void vDisplayData();
};
#endif
MyType.cpp
#include"MyType.h"
void A::vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
void A::vDisplayData(){
cout<<"\nData is: "<<iData<<endl;
}
main.cpp
#include"MyType.h"
typedef A<int,20> MyType;
int main(){
int x = 12;
MyType obj;
obj.vSetData(12);
obj.vDisplayData();
return 0;
}
ERRORS: 10 errors. They are as follows:-
mytype.cpp(2) : error C2955: 'A' : use of class template requires template argument list
mytype.h(9) : see declaration of 'A'
mytype.cpp(2) : error C2955: 'A' : use of class template requires template argument list
mytype.h(9) : see declaration of 'A'
mytype.cpp(2) : error C2065: 'T' : undeclared identifier
mytype.cpp(2) : error C2146: syntax error : missing ')' before identifier 'iPar1'
mytype.cpp(2) : error C2761: 'void A::vSetData(T)' : member function redeclaration not allowed
mytype.cpp(2) : error C2059: syntax error : ')'
mytype.cpp(2) : error C2143: syntax error : missing ';' before '{'
mytype.cpp(2) : error C2447: '{' : missing function header (old-style formal list?)
mytype.cpp(6) : error C2955: 'A' : use of class template requires template argument list
mytype.h(9) : see declaration of 'A'
mytype.cpp(6) : error C2509: 'vDisplayData' : member function not declared in 'A'
mytype.h(9) : see declaration of 'A
Technique 2 -> Works fine.
AboveCodeInOneFile.cpp
#include<iostream>
using namespace std;
template <class T,int iMax>
class A{
T iData;
public:
void vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
void vDisplayData(){
cout<<"\nData is: "<<iData<<endl;
}
};
typedef A<int,20> MyType;
int main(){
int x = 12;
MyType obj;
obj.vSetData(12);
obj.vDisplayData();
return 0;
}
Please let me know what mistake i am doing in Technique 1
When defining a template class, the method definition must be seen by the compiler. So they have to be in the header file.
Edit
You have to include the method implementation, so it's seen by the compiler. You can do it by including them from another `MyType_impl.h" file:
template <class T, int iMax>
void A<T, iMax>::vDisplayData()
{
cout<<"\nData is: "<<iData<<endl;
}
Each method definition needs the full class name decoration above it:
template <typename T>
void A<T>::vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
template <typename T>
void A<T>::vDisplayData(){
cout<<"\nData is: "<<iData<<endl;
}
When you do this however you'll get other compile errors, for the reasons Abhineet outlined. To fix this, you could put the definitions I wrote into the header file, beneath the class declaration, or you could put it in another header (MyType_Inc.h) and include /that/ header in the class declaration header
Technique 1 is wrong for templates. Don't use it.
Think of templates as blueprints for actual functions. Blueprints by themselves are not compilable. Only when you substitute template arguments (<class T,int iMax>) the actual functions are built. Because of this the compiler must see the blueprints when it tries to build functions from templates. In order to see the blueprints they must reside completely in header files.
When you define the member functions, you have to repeat the template parameters
template <class T,int iMax>
void A<T, iMax>::vSetData(T iPar1)
{
if(iPar1 <= iMax)
iData = iPar1;
}
That saves you from the compile errors.
The next problem is that templates defined in a .cpp file can only be used in that file. If you want to use them somewhere else, you really should put the definitions in the header.
There are two problems with your first version.
When implementing a member of a class template outside the class, you need to declare it as a template:
template <class T,int iMax>
void A<T,iMax>::vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
Also, the function definitions need to be available in any compilation unit that instantiates the template. In practice, this means you should usually define them inline (either inside the class template definition, or outside it but in a header file and declared inline). Simply defining them in a source file like you do will cause link errors.