Reputation: 6775
Consider this simple meta query to check integral:
#include <type_traits>
template <typename T>
struct IsIntegralConstant
{
static constexpr bool value = std::is_integral_v<T>;
};
// partial specialization if type destructuring matches an integral_constant
template <typename T, auto N>
struct IsIntegralConstant<std::integral_constant<T, N>>
{
static constexpr bool value = true;
};
template <typename T> constexpr auto isIntegralConstant_v = IsIntegralConstant<T>::value;
// Now I can do queries such as:
static_assert( isIntegralConstant_v<int> );
static_assert( isIntegralConstant_v<std::integral_constant<int, 2>> );
// it'd be nice if it could work for direct values too
// static_assert( isIntegralConstant_v<2> ); ?
// let's see...
template <auto N>
struct IsIntegralConstant<std::integral_constant<decltype(N), N>>
{
static constexpr bool value = true;
};
// gcc:
//error: partial specialization of 'struct IsIntegralConstant<std::integral_constant<decltype (N), N> >' after instantiation of 'struct IsIntegralConstant<std::integral_constant<int, 2> >' [-fpermissive]
//struct IsIntegralConstant<std::integral_constant<decltype(N), N>>
// what ?
// clang says nothing, until we force instanciation:
static_assert( isIntegralConstant_v<2> );
//#1 with x86-64 clang 8.0.0
//<source>:35:38: error: template argument for template type parameter must be a type
play with it: https://godbolt.org/z/dosK7G
It seems when your primary template has made a decision between type or value, then you're simply stuck with that for all specializations.
Is there no way to have a more generic thing such as:
template <autotypename TorV> ... ?
Upvotes: 1
Views: 158
Reputation: 170269
Is there no way to have a more generic thing such as
None whatsoever in any version of C++ so far. And it's also unlikely to change. Despite the loaded name IsIntegralConstant
, we are obviously not going to be testing things like IsIntegralConstant_v<2>
. The utility of templates is in generic code, where nothing is lacking:
template<auto wut>
struct bar {
// static_assert(IsIntegralConstant_v<wut>);
// ill-formed, but we only really care and need
static_assert(IsIntegralConstant_v<decltype(wut)>);
};
Upvotes: 1