mercredi 13 décembre 2017

How to check at compile time that a function may be called at compile time?

I would like to be able to introspect whether or not a function or function object may be called at compile time; that is, whether or not it is constexpr:

template<class Function>
struct is_constexpr;

This is my first attempt, which issues a false positive for the is_not_constexpr_function type:

#include <type_traits>
#include <iostream>

template<class Function>
struct is_constexpr
{
  template<class T,
           auto = decltype(T()())
          >
  static std::true_type test(int);

  template<class>
  static std::false_type test(...);

  static const bool value = decltype(test<Function>(0))::value;
};

struct is_constexpr_function
{
  constexpr void operator()() const
  {
  }
};

struct is_not_constexpr_function
{
  void operator()() const
  {
  }
};

int main()
{
  std::cout << "is_constexpr_function is constexpr function object: " << is_constexpr<is_constexpr_function>::value << std::endl;
  std::cout << "is_not_constexpr_function is constexpr function object: " << is_constexpr<is_not_constexpr_function>::value << std::endl;
}

Program output:

$ clang -std=c++14 is_constexpr.cpp -lstdc++
$ ./a.out 
is_constexpr_function is constexpr function object: 1
is_not_constexpr_function is constexpr function object: 1

Is this possible to do in C++? If so, what might a correct implementation of is_constexpr look like? If not, what approximations might be possible?





Aucun commentaire:

Enregistrer un commentaire