变量模板 "SFINAE" 不工作
variable template "SFINAE" not working
我正在尝试使用 "SFINAE" 实现 cbor 格式的大小代码,因为找不到更好的词。但它不起作用,例如 size_code<3>
,计算结果为 0x1b
。怎么了?
template <::std::size_t N,
typename = ::std::enable_if_t<N <= 0x17>
>
constexpr ::std::uint8_t const size_code = N;
template <::std::size_t N,
typename = ::std::enable_if_t<(N > 0x17) &&
(N <= ::std::numeric_limits<::std::uint8_t>::max())
>
>
constexpr ::std::uint8_t const size_code = 0x18;
template <::std::size_t N,
typename = ::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint8_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint16_t>::max())
>
>
constexpr ::std::uint8_t const size_code = 0x19;
template <::std::size_t N,
typename = ::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint16_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint32_t>::max())
>
>
constexpr ::std::uint8_t const size_code = 0x1a;
template <::std::size_t N,
typename = ::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint32_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint64_t>::max())
>
>
constexpr ::std::uint8_t const size_code = 0x1b;
您不能像那样重新定义变量模板,因此您的代码不应该工作。
使用 constexpr
函数会简单得多,如下所示:
template <typename T> constexpr T t_max = std::numeric_limits<T>::max();
constexpr std::uint8_t size_code (std::size_t n) {
if (n <= 0x17) return n;
if (n <= t_max<std::uint8_t>) return 0x18;
if (n <= t_max<std::uint16_t>) return 0x19;
if (n <= t_max<std::uint32_t>) return 0x1a;
if (n <= t_max<std::uint64_t>) return 0x1b;
}
我的 2 美分:
template <::std::size_t N, typename = void>
constexpr ::std::uint8_t const size_code{};
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N, ::std::enable_if_t<N <= 0x17> > = N;
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N,
::std::enable_if_t<(N > 0x17) &&
(N <= ::std::numeric_limits<::std::uint8_t>::max())
>
> = 0x18;
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N,
::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint8_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint16_t>::max())
>
> = 0x19;
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N,
::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint16_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint32_t>::max())
>
> = 0x1a;
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N,
::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint32_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint64_t>::max())
>
> = 0x1b;
我正在尝试使用 "SFINAE" 实现 cbor 格式的大小代码,因为找不到更好的词。但它不起作用,例如 size_code<3>
,计算结果为 0x1b
。怎么了?
template <::std::size_t N,
typename = ::std::enable_if_t<N <= 0x17>
>
constexpr ::std::uint8_t const size_code = N;
template <::std::size_t N,
typename = ::std::enable_if_t<(N > 0x17) &&
(N <= ::std::numeric_limits<::std::uint8_t>::max())
>
>
constexpr ::std::uint8_t const size_code = 0x18;
template <::std::size_t N,
typename = ::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint8_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint16_t>::max())
>
>
constexpr ::std::uint8_t const size_code = 0x19;
template <::std::size_t N,
typename = ::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint16_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint32_t>::max())
>
>
constexpr ::std::uint8_t const size_code = 0x1a;
template <::std::size_t N,
typename = ::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint32_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint64_t>::max())
>
>
constexpr ::std::uint8_t const size_code = 0x1b;
您不能像那样重新定义变量模板,因此您的代码不应该工作。
使用 constexpr
函数会简单得多,如下所示:
template <typename T> constexpr T t_max = std::numeric_limits<T>::max();
constexpr std::uint8_t size_code (std::size_t n) {
if (n <= 0x17) return n;
if (n <= t_max<std::uint8_t>) return 0x18;
if (n <= t_max<std::uint16_t>) return 0x19;
if (n <= t_max<std::uint32_t>) return 0x1a;
if (n <= t_max<std::uint64_t>) return 0x1b;
}
我的 2 美分:
template <::std::size_t N, typename = void>
constexpr ::std::uint8_t const size_code{};
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N, ::std::enable_if_t<N <= 0x17> > = N;
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N,
::std::enable_if_t<(N > 0x17) &&
(N <= ::std::numeric_limits<::std::uint8_t>::max())
>
> = 0x18;
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N,
::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint8_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint16_t>::max())
>
> = 0x19;
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N,
::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint16_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint32_t>::max())
>
> = 0x1a;
template <::std::size_t N>
constexpr ::std::uint8_t const size_code<N,
::std::enable_if_t<
(N > ::std::numeric_limits<::std::uint32_t>::max()) &&
(N <= ::std::numeric_limits<::std::uint64_t>::max())
>
> = 0x1b;