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