I for one, am looking forward to reflection and metaclasses in C++.
However, I do not like how the properties of a
metaclass are changed inside a
constexpr block. Of course it is being evaluated at compile time, but the expressions may not be constant expressions at the time of evaluation. They could've just used a new keyword like
metaexpr or
genexpr or
haxpr or
hygienic or
hyenas, but instead they chose to use
constexpr and call non
const functions inside it. Maybe
constexpr has different semantics inside a
metaclass.
The definition of
compiler may cause namespace collisions. It should be encapsulated in a
namespace, which may either be introduced by inclusion of a header file or made available inside
metaclass definitions. P0194 proposes a
reflect library, and
compiler could be made part of it.
P0194, P0590, P0598 define a
reflexpr operator, but they is defined to have different behavior by each document. In P0194 and P0590,
reflexpr yields types. In P0590,
$ yields values. In P0598
reflexpr yields values. Introducing
$ to the source character set is a bad bad idea, not all keyboards have the
$ character. I think that the suggestions proposed by P0598 are good for working with a
metaclass, but it has to yield a non
const value to work with them. And this is again in conflict with the existing
constexpr requirements.
#include <reflect> // to access the compiler.function
metaclass interface {
metaexpr {
auto x = reflexpr(interface);
reflect::compiler.require(x.member_variables.empty(), "interfaces may not contain data.");
for (auto &&f : x.member_functions) {
reflect::compiler.require(!f.is_copy() && !f.is_move(), "interfaces may not copy or move; consider a virtual clone() instead");
if (!f.has_access())
f.make_public();
reflect::compiler.require(f.is_public(), "interface functions must be public.");
f.make_pure_virtual();
}
}
virtual ~interface() noexcept {}
};
interface Shape {
int area() const;
void scale_by(double factor);
};
class Sepples : Shape {
static constexpr auto meta_sepples = reflexpr(Shape);
int area() const;
void scale_by(double factor);
};
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0590r0.pdfhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0598r0.htmlhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0194r4.html