Re:Reflection for C++26
by tsimionescu on Tuesday July 02, 2024 @03:09AM
(#40854231)
Note that you should really be using std:print rather than std::cout if using modern C++.
Just because it's newer doesn't make it better. There are good reasons for avoiding iostream
Re:Reflection for C++26
by tsimionescu on Tuesday July 02, 2024 @04:52AM
(#40854750)
That's my point - iostream is a really bad piece of code, and if you're anyway going to use modern C++, it's really recommended to stop using it.
Sorry, I got your comment completely backwards
iostream is good enough for most jobs, unless one is writing high performace IO code battling for each ms.
Re:Reflection for C++26
by tsimionescu on Wednesday July 03, 2024 @10:42AM
(#40866381)
Or unless one wants to write formatted output, or unless one wants to handle IO errors with RAII...
Perfectly fine with existing operators and handle classes.
Happily using iostreams since Turbo C++ 1.0 for MS-DOS in 1993, and will keep doing so, unless chasing ms optimizations.
Re:Reflection for C++26
by spacechild1 on Tuesday July 02, 2024 @05:03AM
(#40854788)
> There are good reasons for avoiding iostream
I guess that's not what you wanted to say, but I fully agree :)
Re:Reflection for C++26
by greenavocado on Tuesday July 02, 2024 @08:33AM
(#40856006)
Fair enough.
Serialization
#include <print>
template<typename T>
void serialize(const T& obj, std::ostream& os) {
for_each(reflect(T), [&](auto member) {
std::print("{}: {}\n", member.name(), member.get(obj));
});
}
Simplified property systems class Person {
public:
Person(const std::string& name, int age)
: name(name), age(age) {}
std::string getName() const { return name; }
void setName(const std::string& name) { this->name = name; }
int getAge() const { return age; }
void setAge(int age) { this->age = age; }
private:
std::string name;
int age;
REFLECT_PROPERTIES(
(name, "Name of the person"),
(age, "Age of the person")
)
};
int main() {
Person person("Alice", 30);
auto properties = reflect::getProperties<Person>();
for (const auto& prop : properties) {
std::print("Property: {} ({})\n", prop.name, prop.description);
auto value = reflect::get(person, prop.name);
std::print("Value: {}\n", value);
if (prop.name == "age") {
reflect::set(person, prop.name, 31);
}
}
std::print("Updated age: {}\n", person.getAge());
return 0;
}
Simplified template metaprogramming template<typename T>
void printTypeInfo() {
constexpr auto info = reflect(T);
std::print("Type name: {}\n", info.name());
std::print("Member count: {}\n", info.members().size());
}
Generic algorithm for printing all members template<typename T>
void printAllMembers(const T& obj) {
for_each(reflect(T), [&](auto member) {
std::print("{}: {}\n", member.name(), member.get(obj));
});
}
Implementing serialization for complex types often requires manual code writing or external tools. With static reflection you could automate this process
Simplified property systems Simplified template metaprogramming Easier to write generic algorithms that work with arbitrary types