Consider the following example:
struct mystruct
{
int a;
int b;
int c;
};
int main()
{
mystruct x;
std :: cout << reinterpret_cast <size_t> (&(x.b)) - reinterpret_cast <size_t> (&x) << std :: endl;
}
What the above does is to use reinterpret_casts to determine the position of member b in memory within the struct mystruct. On my system (and, I guess, on any reasonable system) the above yields 4.
Now, what I would need is to do exactly the same, but at compile time. Is there a way to get such a thing done? What I need is some static constexpr size_t that at compile time will tell me what the position of b is within mystruct.
You can do that with offsetof macro:
size_t constexpr b_offset = offsetof(mystruct, b);
Note, that you cannot use offsetof outside of functions in the same class definition because this class is incomplete yet.
Related
I have a simple struct:
struct Test
{
int a;
Test(int b, int c)
{
a = b * c;
}
};
I need to declare CT TransformData variable. It works with #define:
#define testDefault = Test(1, 2)
But I need to separate this variable to a separate namespace. If I use consexpr I get the error:
the type «const Test» of «constexpr» variable «test» is not literal
I've googled about constexpr and seems constexpr limits don't allow declare such class instance as constexpr.
Which are there ways to declare such constant?
The class you show is actually a good candidate for producing constexpr constants. But its constructor needs to be marked constexpr.
struct Test
{
int a;
constexpr Test(int b, int c)
: a(b*c) // must be initialized up to C++20
{
a = b * c + 1; // but can still be reassigned
}
};
A "literal type" is a normative term for types that can produce constant expressions. Your compiler was telling you that one of the requirements is missing.
I know from c++ primer that we can use typedef in the following ways:
typedef int mytype;
typedef int *mytype;
However, the following code also compiles, and it seems to create a new type "rt", I am curious what is the type of rt, and what are common uses of this kind of typedef?
class A{
public:
int c;
};
typedef int A::* rt;
It is not a "three elements typedef", it is a pointer to member variable typedef. You can find more information about pointer to member variable here.
In your precise case, it allows you to instantiate variables of type "rt" that will point to a precise member of type int of A class, and then use it to access this member on A instances.
#include <iostream>
class A{
public:
int c;
};
typedef int A::* rt;
int main() {
A instance;
rt member; // This is a pointer to A member.
member = &A::c; // This pointer will point on c member of A class
instance.c = 0;
instance.*member += 2; // As member point on c, this code access to the c member.
std::cout << instance.c << std::endl; // This will now output "2".
}
It's pointer to member variable.
You define it with this syntax: int A::* pointer;, and initialize it $A::c and read it's value instance.*pointer.
A instance;
int A::* pointer = &A::c;
instance.*pointer = 10;
Actually it's an offset from beginning of the class that allow you to hold a pointer to int that is a member variable of class A.
I have this header:
class A{
const int x;
typedef std::array<MyClass, x> ARRAY; // Cannot use x here?
};
and in the implementation file:
A::A() : x(10) {}
but I get compiler errors for the typedef line saying:
invalid use of non-static data member A::x
I thought x only had to be const for use in the array sizing? I really wish to avoid static.
In order to use x as a non-type template parameter, it has to be a core constant expression - basically it has to be evaluatable at compile-time. A simple const is not sufficient criteria, const just means it is not modifiable in the future - it does not mean that it is a known quantity at compile-time.
There is one edge case here which may be causing some confusion in that a const integral is a core constant expression in cases like this:
const int x = 10;
std::array<int, x> arr; // ok
There's no reason to want to avoid static. You will want to do something like this:
struct A {
static constexpr int x = 10;
typedef std::array<MyClass, x> ARRAY;
};
How should I write a constructor for a class to initialize a member that is a const structure / has const fields?
In the following example, I define a constructor within structure B and it works fine to initialize it's const fields.
But when I try to use the same technique to initialize const fields of structure C within class A it doesn't work. Can someone please help me and rewrite my class A in a way, that it starts working?
#include <iostream>
class A
{
public:
struct C
{
C (const int _x) : x (_x) {}
const int x;
};
C c (3);
};
int main (int argc, char *argv[])
{
struct B
{
B (const int _x) : x (_x) {}
const int x;
};
B b (2);
std::cout << b.x << std::endl;
A a;
std::cout << a.c.x << std::endl;
return 0;
}
P.S.
I did some search and I think, I understand, that unless I have C++11 support or want to use boost library, I have to define a helper function to initialize a const struct within initialization list
(C++ Constant structure member initialization)
but it seems to be crazy that I have to define alike struct, but with non const fields to initialize a struct with const fields, doesn't it?
Another thing that I found tells that I should initialize const members in a constructor of the class A, rather than in a constructor of the struct C (C++ compile time error: expected identifier before numeric constant) but it also seems crazy to me, because why should I rewrite a class constructor every time I want to add a new struct, isn't it more convenient to have a separate constructor for each struct C within the class A?
I would be grateful to any comments that could possibly clarify my confusion.
I'd do the job like this:
#include <iostream>
class A {
public:
struct C {
C(const int _x) : x(_x) {}
const int x;
};
C c; // (3);
A() : c(3) {}
};
int main(int argc, char *argv []) {
A a;
std::cout << a.c.x << std::endl;
return 0;
}
Note that it's not a matter of using a ctor in A or in C, but of the ctor for A telling how the ctor for C should be invoked. If the value that will be passed will always be 3 that's not necessary, but I'm assuming you want to be a able to pass a value of your choice when you create the C object, and it will remain constant after that.
If the value will always be the same (3 in this case) you can simplify things a lot by also making the constant static:
struct A {
struct C {
static const int x = 3;
};
C c;
};
int main() {
A a;
std::cout << a.c.x << "\n";
}
So, if the value is identical for all instances of that class, make it static const, initialize it in place, and life is good. If the value is not known until you create an instance of the object, and remains constant thereafter for the life of that object, you need to pass it in through the constructors.
For a slightly different case, there's a third possibility: if C is an independent class (not nested inside of A) you might have a situation where other instances of C use various values, but all instances of C inside an A always use the same value. In this case, you'd do something like:
struct C {
const int x;
C(int x) : x(x) {}
};
struct A {
C c;
A() : c(3) {}
};
Of course, you can do the same thing when C is nested inside of A, but when/if you do, it generally means you're setting the same value for all instances of C, so you might as well use the static const approach instead. The obvious exception would be if A had multiple constructors, so (for example) A's default constructor passed one value for C::x and its copy constructor passed a different value.
Suppose I have following template class:
template<unsigned char I, unsigned char F>
class FOO
{
....
}
In the main function, I have many such variables, with different (I, F), like following,
int main()
{
.....
FOO<4, 2> a;
FOO<6, 3> b;
......
}
I want to retain the value of I or F for the defined variables in my main function. Of course, I can define a public/private members for FOO and save the value of (I, F) inside the FOO's constructor, like
template<I,F>
FOO<I,F>::FOO(){
i = I;
f = F;
}
Disadvantage of this method is obvious: It enlarge the size of the FOO. IMO, (I, F) of any variable can be determined at compiling time, so there should be a way to do this without creating local variable.
The usual way (like std::array in C++11) is to do the following:
constexpr unsigned char i() const { return I; }
constexpr unsigned char f() const { return F; }
If your compiler doesn't support constexpr, remove it.
Within your class definition, you can simply refer to the parameters literally (just like any other template parameters!).
But suppose you have this:
typedef Foo<10, 20> MyFoo;
MyFoo x; // what is I, what is K?
The customary thing is to reflect the template parameters inside the class definition:
template <int A, typename T> struct Foo
{
static int const a_value = A;
typedef T type;
// ...
};
Now you can say: MyFoo::type x; return MyFoo::a_value; etc. Note that integral static class constants don't usually need a definition unless you do something like take their address, so in most cases this won't have any cost in the compiled code -- the compiler simply substitutes the value whenever it sees the name of the constant.
you can simply use the template parameters, like this:
#include <iostream>
using namespace std;
template<unsigned char I, unsigned char F>
class FOO
{
public:
void bar() {
cout << "I is: "<<I<<endl;
}
char getI() {
return I;
}
};
using namespace std;
int main(){
FOO<4,2> a;
a.bar();
cout << "getI:"<<a.getI()<<endl;
}
you don't need a copy, as in your example (i = I)
BTW: fully capitalized names like FOO are usually by convention reserved for preprocessor Macros.