2

In C++20, NTTP extends new types which brings us the term structural:

  • l-value ref
  • integral
  • pointer, pointer to member, and null pointer
  • enumeration
  • floating point
  • A class in which: all base classes and non-static data members are public and non-mutable and the types of data members and base classes must also be structural recursively (I guess) and also the array.

From: https://en.cppreference.com/w/cpp/language/template_parameters

Here is a work around implementation that won't simply work:

template <auto>
struct nttp_test {};

template <typename T, typename = void>
struct is_structural : std::false_type {};

template <typename T>
struct is_structural<T, std::void_t<nttp_test<T{}>>> : std::true_type {};

template <typename T>
inline constexpr bool is_structural_v = is_structural<T>::value;

I'm not entirely sure if that works but I'm worried about the default initialization (I can't also use std::declval).

If it's impossible to implement, does it involve compiler magic?

Desmond Gold
  • 1,517
  • 1
  • 7
  • 19
  • 1
    This solves part of your problem, by having a compile time_error if you try to use `is_structural` with a non-structural type `T`: https://godbolt.org/z/Ts9Gzz5aa (it could probably be fixed to be `false`, but I couldn't manage it) – Artyer Aug 20 '21 at 01:21

2 Answers2

4
template <auto>
struct nttp_test {};

template<class T> 
concept structural = requires { []<T x>(nttp_test<x>) { }; };

Demo.

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
2

One more C++20 construct could be of help here:

template<auto> class Meow {};

template<class T> concept meow = requires { typename Meow<T{}>; };

struct Nyan {};

int main() {
        std::cout << std::boolalpha << meow<int> << '\n';
        std::cout << std::boolalpha << meow<Nyan> << '\n';
        std::cout << std::boolalpha << meow<std::string> << '\n';
}

To convert a concept into a good old trait, well... template<class T> using is_meow = std::bool_constant<meow<T>>;.

bipll
  • 11,747
  • 1
  • 18
  • 32