Reputation: 1662
Is it possible to modify type definitions at runtime? For example if you were to define a class like this
class Test {
public:
int x;
int y;
};
could I remove the x or y field from the class at runtime? Or could I add more fields to this like adding a z field?
EDIT: This question is strictly out of curiosity.
Upvotes: 2
Views: 349
Reputation:
C++, by legacy from C, stores as little information as possible at run-time. For this reason, it does not support introspection and does not keep a run-time definition of the data types. On the opposite, the layout of structures is kept implicit, by having the correct offsets used in address computations. Thus the complete layout must be known at compile-time.
Upvotes: 1
Reputation: 64
No. It is definitely impossible.
For example, we are updating the field x in the structure Test and we must know the size at the compile time because of operations on machine code level performs on data offsets
class Test {
public:
int x;
int y;
};
int main(){
Test t;
t.x = 10;
return t.x - 1;
}
Expands to
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-8], 10
mov eax, DWORD PTR [rbp-8]
sub eax, 1
pop rbp
ret
We are accessing the field x by direct writing the value into the address [rbp-8] (rbp holds the current frame pointer). We are subtracting 8 instead of adding because of the stack grows from the upper address to the lower.
But with C++ standard library and some masochistic tendencies you can write something like that (holding values in the variable 'values')
#include <any>
#include <iostream>
#include <map>
#include <string>
class Test {
public:
int x;
int y;
};
int main(){
std::unordered_map<std::string, std::any> values;
values.insert({"pi", 3.14f});
values.insert({"test", Test{1,1}});
std::cout<< std::any_cast<float>(values["pi"])<<std::endl;
std::cout<< std::any_cast<Test>(values["test"]).x<<std::endl;
}
Upvotes: 4
Reputation: 179799
No. You can do this at compile time, with some effort. C++ has template
s. You can use a template argument to choose between different variants of Test
, some with x
and some with a z
. But the template argument has to be a compile-time constant. You cannot get it from std::cin
.
Upvotes: -1