constexpr initializers and enum template arguments - templates

I'm noticing something strange in my code when I use constexpr initializers and enum template argumets. For example, the following code will compile:
enum class TestEnum1 {
Val1,
Val2
};
template <TestEnum1 EnumVal> class TestClass1 {
public:
constexpr TestClass1() {
}
};
class TestClass2 {
public:
TestClass1<TestEnum1::Val1> TestObject = TestClass1<TestEnum1::Val1>();
};
int main() {
TestClass2 testObj;
}
while the following will not:
enum class TestEnum1 {
Val1,
Val2
};
template <typename T, TestEnum1 EnumVal> class TestClass1 {
public:
constexpr TestClass1() {
}
};
class TestClass2 {
public:
TestClass1<int, TestEnum1::Val1> TestObject = TestClass1<int, TestEnum1::Val1>();
};
int main() {
TestClass2 testObj;
}
note that I only added another template argument before the existing one. The error message is something like:
error: 'enum class TestEnum1' is not a class or a namespace
error: expected ';' at end of member declaration
error: expected unqualified-id before '>' token
error: expected unqualified-id before ')' token
error: template argument 1 is invalid
Glad if someone would explain why or at least solve the problem. I'm using g++5.3 with --std=c++11 and windows 10.
EDIT: I just tested enum, under which circumstance errors still occurred, but with the first item on the error list removed. Tested int and everything went fine.

Related

Templated class-- semicolon after constructor?

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.

VS compiling error when passing arguments to c++ constructor

I'm trying to pass two arguments to a constructor:
class CTest1
{
public:
CTest1(const int i8BitImageID, const int i256BitImageID) : m_i8BitImageID(i8BitImageID), m_i256BitImageID(i256BitImageID) {};
private:
int m_i8BitImageID;
int m_i256BitImageID;
};
#define BITMAP_1_ID 1
#define BITMAP_2_ID 2
class CTest2
{
public:
CTest1 test1(BITMAP_1_ID, BITMAP_2_ID); // Compile error here
};
When I compile this (using Visual Studio 2017), the line where I declare "test1" results in a "C2059: syntax error: 'constant'" error. I've tried with an without "const" in the definition of the constructor.
Thanks!
Default member initializer only works with brace or equals initializer. e.g.
class CTest2
{
public:
CTest1 test1 = CTest1(BITMAP_1_ID, BITMAP_2_ID);
CTest1 test2 {BITMAP_1_ID, BITMAP_2_ID};
};
Or you could use member initializer list.
class CTest2
{
public:
CTest2() : test1(BITMAP_1_ID, BITMAP_2_ID) {}
CTest1 test1;
};

cascades of templates does not work

I am a beginner of c++ meta programming.
Now I test a code which is on a text book.
The following code is a copy of the code but it give me an error message
at line(1). At line(1), it seems the code tries to call Layer2::function with template keyword because it is following another template. Unfortunately, my compiler give me an error message, "error: expected ‘;’ before ‘::’ token.". Can anyone find a problem of the code?
Thank you very much.
template<typename T>
class Layer0 {
public:
template<int L1>
class Layer1 {
public:
template<int L2>
class Layer2 {
public:
virtual void function(void);
};
};
};
template<typename T, int L1>
class LayerTest {
public:
void pointer (typename Layer0<T>::template Layer1<L1>::template Layer2<L1>* ptr) {
// At the following line(1), I got an error message, error: expected ‘;’ before ‘::’ token.
ptr->template Layer2<L1>::function(); // (1) inhibit call of virtual function
}
};

template class instantiation in another class in c++

I have a template class that when I instantiate in main doesn't have any issues but when i try instantiating the same in another class is giving issues. can someone please enlighten me on the solution for this
#include<iostream>
#include<string>
using namespace std;
template <class T>
class property {
public:
property(string name)
{
propertyName= name;
}
private:
T item;
string propertyName;
};
main()
{
property<int> myIntProperty("myIntProperty");
}
the above code compiles with out any issue.
but
#include<iostream>
#include<string>
using namespace std;
template <class T>
class property {
public:
property(string name)
{
propertyName= name;
}
private:
T item;
string propertyName;
};
class propertyHolder
{
property<int> myIntProperty("myIntProperty");
};
this code is not getting compiled.
giving me error like
main.cpp|19|error: expected identifier before string constant|
main.cpp|19|error: expected ',' or '...' before string constant|
Thanks,
Harish
property<int> myIntProperty("myIntProperty");
This is a function declaration, so it expects you to insert a default argument after identifying it, like string s = "myIntProperty".
Perhaps you want to initialize an object called myIntProperty,
property<int> myIntProperty {"myIntProperty"};
This can be done in C++11, but you can also initialize it in the constructor initializer list,
// Header
class propertyHolder {
public:
propertyHolder( string s );
private:
property<int> myIntProperty;
};
// Source
propertyHolder::propertyHolder( string s ) :
myIntProperty( s )
{
}
You wanted to declare field in class propertyHandler. That syntax is not working because you cannot declare a field and assing it value at the same spot.
You can delcare it, and initialise in constructor:
property<int> myIntProperty;
propertyHolder(): myIntProperty("name") {}
or with c++11 syntax:
property<int> myIntProperty{"name"};
or declare it static, and them declare like that:
static property<int> myIntProperty;
and after class declaration:
property<int> propertyHolder::myIntProperty("name");

Returning a double pointer to an object of template class

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.