Ниже приведена реализация is_constexpr
для функций , а не для произвольных выражений, для C ++ 11 и C ++ 17. Это требует, чтобы аргументы функции, которую вы хотите проверить, были конструктивными по умолчанию.
#include
struct A {}; // don't make it too easy, use a UDT
A f1(A a) { return a; } // is_constexpr -> false
constexpr A f2(A a) { return a; } // is_constexpr -> true
// The following turns anything (in our case a value of A) into an int.
// This is necessary because non-type template arguments must be integral
// (likely to change with C++20).
template constexpr int make_int(T &&) { return 0; }
// Helper to turn some function type (e.g. int(float)) into a function
// pointer type (e.g. int (*)(float)).
template struct signature_from;
template struct signature_from {
using type = R(*)(Args...);
};
// See std::void_t for the idea. This does it for ints instead of types.
template using void_from_int = void;
// The fallback case: F is not a function pointer to a constexpr function
template ::type F, class = void_from_int<>>
struct is_constexpr {
static constexpr bool value = false;
};
// If void_from_int doesn't lead to a substitution
// failure, then this is the preferred specialization. In that case F must
// be a function pointer to a constexpr function. If it is not, it could
// not be used in a template argument.
template ::type F>
struct is_constexpr>
{
static constexpr bool value = true;
};
// proof that it works:
static_assert(!is_constexpr::value, "");
static_assert( is_constexpr::value, "");
#if __cplusplus >= 201703
// with C++17 the type of the function can be deduced:
template struct is_constexpr2 : is_constexpr, F> {};
static_assert(!is_constexpr2::value, "");
static_assert( is_constexpr2::value, "");
#endif
См. Это в действии в https://godbolt.org/g/rdeQme .
C:\Desktop>curl --head https://www.google.com/ --proxy 1.1.1.1:8080