When I try to call a function, passing in a reference to my variable which has the type int, to the function which takes a type of int, I get an error that seems to point out that the int is the type of the class it was declared in, why is this?
Header:
class MyClass {
public:
int MAJOR = 3;
int MINOR = 3;
int REV = 0;
}
Code:
glfwGetVersion(&MyClass::OPENGL_VERSION_MAJOR, &MyClass::OPENGL_VERSION_MINOR, &MyClass::OPENGL_VERSION_REV);
Error:
error: cannot convert 'int MyClass::*' to 'int*' for argument '1' to 'void glfwGetVersion(int*, int*, int*)'
Change to:
class MyClass {
public:
static const int MAJOR = 3;
static const int MINOR = 3;
static const int REV = 0;
};
If these versions are constant.
Otherwise as:
class MyClass {
public:
static int MAJOR;
static int MINOR;
static int REV;
};
Then somewhere in a .cpp file
int MyClass::MAJOR = 3;
int MyClass::MINOR = 3;
int MyClass::REV = 0;
Check live example here
&MyClass::OPENGL_VERSION_MAJOR is a pointer on member.
You may use
MyClass instance;
glfwGetVersion(&instance.OPENGL_VERSION_MAJOR,
&instance.OPENGL_VERSION_MINOR,
&instance.OPENGL_VERSION_REV);
Related
class PTM {
public:
int iValue;
static float fValue;
};
int main() {
int PTM::*piValue = &PTM::iValue; // OK: non-static
float PTM::*pfValue = &PTM::fValue; // C2440 error: static
float *spfValue = &PTM::fValue; // OK
}
I am confused on what "*piValue" means. Is that a pointer p for variable iValue?
I have tried to solve this, but I can't. I have a class definition and I want a member function (siz) to return a constant value to another member function (abc). This value is used as maximum index in an array declaration in that function. But this doesn't seems to work. Here is a simplified version:
class bin {
constexpr int siz();
public:
void abc();
};
constexpr int bin::siz() {
const int sizz = sizeof(int) * 8;
}
void bin::abc() {
char arr[siz()]; // compiler: this expression didn't evaluate as constant (¿?)
};
However, this other very similar code (but using simple functions) does compile...
constexpr int siz() {
const int sizz = sizeof(int) * 8;
return sizz;
}
int main() {
char arr[siz()];
return 0;
}
I am not entirely sure but I think the problem is that in bin::abc, the object can be anything at run time. Hence, bin::siz() cannot be evaluated at compile time.
The following works fine
int main()
{
bin b;
char arr[b.siz()];
}
after changing bin to:
class bin {
public:
constexpr int siz();
};
constexpr int bin::siz() {
return sizeof(int) * 8;
}
If siz does not depend on the state of the object, as in your posted code, I suggest making it a static member function.
The following works fine for me.
class bin {
public:
static constexpr int siz();
void abc() const;
};
constexpr int bin::siz() {
return sizeof(int) * 8;
}
void bin::abc() const {
char arr[siz()];
}
int main()
{
bin b;
char arr[b.siz()];
}
Lets say I have this prog.cc file:
struct MyStruct
{
unsigned int X : 2;
unsigned int Y : 2;
unsigned int Spare : 28;
};
void MyFunc (int x, MyStruct myStruct = 0);
int main ()
{
MyStruct myStr;
myStr.X = 1;
myStr.Y = 0;
MyFunc(6);
}
void MyFunc (int x, MyStruct myStruct)
{
x += 10;
}
When compiled with GCC 4.4.7, I got this error:
prog.cc:7: error: default argument for 'MyStruct myStruct' has type 'int'
Now, I understand the error, but still - how can I resolve this?
I know I need somehow to cast from int to MyStruct, but both
MyStruct myStruct = (MyStruct)0
and
MyStruct myStruct = static_cast<MyStruct>0
has failed with:
prog.cc:7: error: no matching function for call to 'MyStruct::MyStruct(int)'
prog.cc:1: note: candidates are: MyStruct::MyStruct()
prog.cc:1: note: MyStruct::MyStruct(const MyStruct&)
How can I simply initialize my user-defined struct, passed as default argument on function parameter?
(Here is the sample code:
http://melpon.org/wandbox/permlink/izWCnBXl9PGnmm0l)
You can default-initialise PODs, so:
void MyFunc (int x, MyStruct myStruct = MyStruct());
I guess you're trying to use 0 because, as well as being an integer, that's a null pointer constant. But you're not using pointers here. The use of 0 is the wrong approach.
Just add a conversion constructor to your MyStruct:
struct MyStruct
{
unsigned int X : 2;
unsigned int Y : 2;
unsigned int Spare : 28;
MyStruct(int n) : X(n&3), Y(n&12), Spare(0) {}
};
It's implementation depends on your semantics, but you get the technical point. Enclosing your struct in an union could be a good solution too if you want to make it convertible from/to an int.
I have this small piece of code:
int add(int x, int y)
{
return x + y;
}
class A
{
public:
const static int (*FP)(int, int) = &add;
};
int main()
{
int x = 3;
int y = 2;
int z = A::FP(x, y);
return 0;
}
Under VS2012 this generates the following error:
error C2864: 'A::FP' : only static const integral data members can be initialized within a class.
Is there something I am not seeing? Or is it plainly not possible for some reason?
Christian
Initialize outside of the class definition, using a typedef to make the constness possible:
typedef int (*func_t)(int, int);
class A
{
public:
const static func_t FP;
};
const func_t A::FP = &add;
Without the typedef the declaration:
const static int (*FP)(int, int) = &add;
is a static function pointer named FP with a return type of const int, not a const function pointer. When compiled with warnling level /W4 the following diagnostic is emitted:
warning C4180: qualifier applied to function type has no meaning; ignored
this was not immediately apparent due to the ordering of the declaration, const static int instead of static const int.
In C++03. In class initialization of non-intgeral or enum data-types is not allowed.
class A
{
public:
typedef int (*FP_ptr)(int, int);
const static FP_ptr FP;
};
const A::FP_ptr
A::FP = &add;
C++11
class A
{
public:
constexpr static int (*FP)(int, int) = &add;
};
Thanks a lot, guys. I had pretty much the same problem recently. Just want to add the answer with "const" in the right place without declaring a new type:
class A
{
public:
static int (* const FP)(int, int);
};
int (* const A::FP)(int, int) = &add;
It is okay, to change the last line to(I am not sure if it is exactly the same thing, but it works):
int (* const A::FP)(int, int) = add;
The other way (how other people solve similar issue) would be something like:
class A
{
public:
static int FP(int, int);
};
int A::FP(int x, int y)
{
return add( &x, &y );
}
I have a mechanism like the following for retrieving certain parameters for a limited number of different types of objects I need to handle:
template <class T>
struct params {};
template <>
struct params<FooObj>
{
static const int paramA = 17;
static const int paramB = 29;
};
this simplifies my code later because in a switch statement when I handle treating different objects, if I get a FooObj then all I have to do is something like this:
typedef params<FooObj> paramsT;
and then in that code snippet I have access to parameters to work with that FooObj via paramsT::paramC or whatever.
Now I have run into an object where I have something like this:
template <>
struct params<BarObj>
{
static const int paramA = 0;
static const int paramB = 9;
static const int paramC = 17;
static const int paramD1 = 18;
static const int paramE1 = 20;
static const int paramD2 = 28;
static const int paramE2 = 30;
static const int paramD3 = 38;
static const int paramE3 = 40;
static const int paramD4 = 48;
static const int paramE4 = 50;
static const int paramD5 = 58;
static const int paramE5 = 60;
static const int paramD6 = 68;
static const int paramE6 = 70;
};
and when I'm handling this object I started writing something like the following:
typedef params<BarObj> paramsT;
BarObj bar;
//load the first 3 params via the above info into bar
int a,b;
for (int i = 1; i <= 6; ++i)
{
a = doSomethingA(bla + paramsT::paramD1);
b = doSomethingB(bla + paramsT::paramE1);
bla.paramD1 = functionOf(stuff,and,a,b);
}
but of course the above has 1 hardcoded into it, and it would ideally read something like this:
typedef params<BarObj> paramsT;
BarObj bar;
//load the first 3 params via the above info into bar
int a,b;
for (int i = 0; i < 6; ++i)
{
a = doSomethingA(bla + paramsT::paramD[i]);
b = doSomethingB(bla + paramsT::paramE[i]);
bla.paramD[i] = functionOf(stuff,and,a,b);
}
although for something like the above I would need the params template specialization to be something like this:
template <>
struct params<BarObj>
{
static const int paramA = 0;
static const int paramB = 9;
static const int paramC = 17;
static const int paramD[] = {18, etc..};
static const int paramE[] = {20, etc..};
};
which doesn't compile because the arrays even though hardcoded are non-integral types. Is there an easy patch around this that wouln't hopefully look too different from my current usage? Or a way to get that array stuff in there?
The "static implicitly inline function static local variable" hack:
template<typename T>
struct params;
struct Bob;
template<>
struct params<Bob> {
static int paramE(unsigned int idx) {
static const int v[] = {18, 20, 22, 24};
return v[idx];
}
};
#include <iostream>
int main() {
for(auto i = 0; i < 4; ++i)
std::cout << params<Bob>::paramE(i) << "\n";
}
note that the resulting values are not "compile time constants" (ie, cannot be used for things like template parameters), but are trivial for compilers to optimize into constants.
You can initialize static const arrays, just not inside the class, as in this Stack Overflow question. The challenge is that you have to do the initialization exactly once per compilation unit, so it's most often done in source (.cpp) files, - therefore, it will be far away from the rest of your initialization, which is fairly gross.