The code below prints unsigned int
as the underlying type of all the constants inside the enum Test
#include <iostream>
#include <type_traits>
#include <typeinfo>
#include <cxxabi.h>
struct Test
{
enum { a = true, b = 1 };
};
static_assert(std::is_same<
std::underlying_type_t<decltype(Test::a)>,
std::underlying_type_t<decltype(Test::b)>>::value, ""
);
int main()
{
int status;
auto const& bi = typeid(std::underlying_type_t<decltype(Test::a)>);
std::cout << abi::__cxa_demangle(bi.name(), 0, 0, &status); // unsigned int
}
Live Example. This also happens if Test
contains two separate enum
s with a
and b
as before.
Question: is it possible to detect that Test::a
is initialized with bool
and Test::b
with int
? Is there any experimental code for this in any of the Reflection Study Group proposals for C++17?
NOTE: I know I can work around it by replacing Test
with
struct Test
{
static constexpr auto a = true;
static constexpr auto b = 1;
};
but I find the enum
version slightly less verbose in its usage.
It is not possible and I consider it very unlikely that it will ever be possible.
The reason is that a
and b
are values of the (in your case unnnamed) enum
. Thus they are, by definition, of the type of the enum
, meaning: Of the same type. The expressions used to initialize them and their respective types are only used to "calculate" the underlying type of the enum
, not of any individual values.
Considering this fact, I think that even reflection will not help to recover the information as the type of the initializing expression is abstracted away when you look at an enum
's value.
What you'd need is an even deeper level of inspection where you'd need to access the expression used to initialize the values. That would mean that compilers will have to store a lot of additional information for every variable, values, etc. (since this would be a general thing not just for enum
s).
Consider what that means:
The last point is what I would consider the real catastrophe for the language. A value should have a single type, the expression used to initialized the value should not be accessible in any way. This is what abstraction is about, breaking it could lead to all kinds of subtle dependencies and a lot of complexity.
Disclaimer: This is just my personal opinion, I can't speak for anyone on the committee or in the working groups.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With