2

There are two operators in C++ that can be called both on types and on variables: sizeof and typeid.

Suppose we want to implement our own operation with a similar behavior, something like*:

template<bool is_type>
struct type_traits_T;

template<>
struct type_traits_T<true> {
    template<typename T>
    struct type_traits {
        using mydecltype = T;
        // and other stuff...
    };
};

template<>
struct type_traits_T<false> {
    template<auto VAR>
    struct type_traits:
        type_traits_T<true>::type_traits<decltype(VAR)> {};
};

This could have worked quite nicely, with a macro:

#define type_traits(V) type_traits_T<is_type(V)>::type_traits<V>

The missing part for the above is the is_type(V) part.

Is there a way to implement is_type(V) that would result with true in case V is a type, and false if V is a variable? If not, would there be a way to achieve that with the static reflection proposal?


* The use of a template to capture the variable has its own restrictions. It may be refactored by moving the call to decltype into the macro. However the question doesn't focus on the template part, which is here just for the purpose of having a simple and viable use case.

Amir Kirsh
  • 12,564
  • 41
  • 74
  • You can't pass a type to a function. Would you be okay with `is_type_v` which yeilds true if `V` is a type and false otherwise? – NathanOliver Sep 25 '20 at 13:23
  • @NathanOliver it is presented with a call syntax having a (false?) notion that the solution might be a macro. But yes, a template is perfectly fine and even preferred. – Amir Kirsh Sep 25 '20 at 13:26
  • Just found this [quite similar question](https://stackoverflow.com/questions/38462104/getting-the-type-of-a-typename-or-expression), with a mind blowing [neat answer!](https://stackoverflow.com/a/38462523/2085626) The solution there works without templates, thus it is much more generic and can work also with variables that cannot be template parameters. – Amir Kirsh Oct 01 '20 at 14:25

1 Answers1

3

You can use function templates:

template<typename>
constexpr bool is_type() {
    return true;
}

template<auto>
constexpr bool is_type() {
    return false;
}

#define type_traits(V) type_traits_T<is_type<V>()>::type_traits<V>
Artyer
  • 31,034
  • 3
  • 47
  • 75