gpt4 book ai didi

c++ - 如何创建一个返回类型的 constexpr 函数(用于模板参数)

转载 作者:IT老高 更新时间:2023-10-28 22:33:37 25 4
gpt4 key购买 nike

我正在寻找基于模板参数编号创建具有模板参数类型的类的某种方法。

我想做的是这样的:

template<size_t n>
constexpr auto type_from_size() {
if(n < 256) {
return uint8_t;
} else {
return uint16_t;
}
}

template<size_t n>
class X {
type_from_size<n>() t;
}

X<500> x;
x.t = 500;

因此,在上面的代码中,constexpr 函数 type_from_size() 将接收数字 500 并返回类型 uint16_t,并且这将是成员 X.t 的类型。

我知道这显然是很糟糕的代码,但是使用模板可以做到吗?

最佳答案

函数不能返回类型。您应该使用模板。

对于仅在两种类型之间进行选择,built-in std::conditional足够了。

#include <type_traits>
#include <cstdint>

template <size_t n>
using type_from_size = typename std::conditional<(n < 256), uint8_t, uint16_t>::type;
// ^ if `n < 256`, the ::type member will be typedef'ed to `uint8_t`.
// otherwise, it will alias to `uint16_t`.
// we then give a convenient name to it with `using`.

template <size_t n>
struct X {
type_from_size<n> t;
// ^ use the template
};

如果您需要支持两个以上的值,您可以像 if/else if/else 链一样将多个 conditional 一起更改,但是 OH MY EYES

template <size_t n>
using type_from_size =
typename std::conditional<(n <= 0xff), uint8_t,
typename std::conditional<(n <= 0xffff), uint16_t,
typename std::conditional<(n <= 0xffffffff), uint32_t,
uint64_t
>::type
>::type
>::type;

您还可以将特化与 std::enable_if (SFINAE) 一起使用,使其更加“低级”:

template <size_t n, typename = void>
struct type_from_size_impl;
// Declare a "size_t -> type" function.
// - the `size_t n` is the input
// - the `typename = void` is a placeholder
// allowing us to insert the `std::enable_if` condition.

template <size_t n>
struct type_from_size_impl<n, typename std::enable_if<(n <= 0xff)>::type> {
using type = uint8_t;
};
// We add a partial specialization
// - in `std::enable_if<c>::type`, if `c` is true, `::type` will be typedef'ed to `void`
// - otherwise, `::type` will not be defined.
// - if `::type` is not defined, substitution failed,
// meaning we will not select this specialization

template <size_t n>
struct type_from_size_impl<n, typename std::enable_if<(n > 0xff && n <= 0xffff)>::type> {
using type = uint16_t;
};

template <size_t n>
struct type_from_size_impl<n, typename std::enable_if<(n > 0xffff && n <= 0xffffffff)>::type> {
using type = uint32_t;
};

template <size_t n>
struct type_from_size_impl<n, typename std::enable_if<(n > 0xffffffff)>::type> {
using type = uint64_t;
};

template <size_t n>
using type_from_size = typename type_from_size_impl<n>::type;
// Here we want to find a specialization of `type_from_size_impl<n>`
// All 4 specializations will be tried.
// If only one specialization works, we will use that one
// (Which is why we need to ensure the ranges are not overlapping
// otherwise the compiler will complain)
// Then we take the `::type` out the complete this "type-level function".

关于c++ - 如何创建一个返回类型的 constexpr 函数(用于模板参数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37486137/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com