gpt4 book ai didi

c++ - 依赖于 char 符号的专用结构模板

转载 作者:行者123 更新时间:2023-12-05 01:04:37 26 4
gpt4 key购买 nike

我有一个函数 template<typename T> void frobnicate()做的东西。我需要 T 成为少数几个选择类型之一,并且我需要一些关于这些类型的信息。我通过提供特征来做到这一点:

template<typename T_Raw>
struct FrobnicationTraits
{
static constexpr bool isValidFrobnicationType = false;
};

template<>
struct FrobnicationTraits<unsigned char>
{
static constexpr bool isValidFrobnicationType = true;
static constexpr bool isUnsigned = true;
static constexpr unsigned char minValue = 0;
static constexpr unsigned char maxValue = 255;
//Elided in each specialization: some other values that are needed by frobnicate()
};

template<>
struct FrobnicationTraits<signed char>
{
static constexpr bool isValidFrobnicationType = true;
static constexpr bool isUnsigned = false;
static constexpr signed char minValue = -128;
static constexpr signed char maxValue = 127;
};

//Elided: versions for unsigned short and signed short

然后:

template<typename T, typename = typename std::enable_if<FrobnicationTraits<T>::isValidFrobnicationType>::type>
void frobnicate()
{
using Traits = FrobnicationTraits<T>;
auto promotedMinValue = +Traits::minValue;
auto promotedMaxValue = +Traits::maxValue;
std::cout << "Frobnicating with " << (Traits::isUnsigned ? "unsigned" : " signed") << " type of size " << sizeof(T) <<" between " << promotedMinValue << " and " << promotedMaxValue << std::endl;
//...
}

这适用于这些调用:

int main()
{
frobnicate<unsigned char>(); // Prints "Frobnicating with unsigned type of size 1 between 0 and 255"
frobnicate< signed char>(); // Prints "Frobnicating with signed type of size 1 between -128 and 127"
frobnicate<unsigned short>(); // Prints "Frobnicating with unsigned type of size 2 between 0 and 65535"
frobnicate< signed short>(); // Prints "Frobnicating with signed type of size 2 between -32768 and 32767"
//frobnicate<unsigned int>(); // Correctly fails to compile, because the enable_if is not satisfied, since FrobnicationTraits<unsigned int> uses the default FrobnicationTraits where isValidFrobnicationType is false
return 0;
}

但现在我希望能够正确 frobnicate<char>() .
char被实现定义为有符号或无符号,但它总是被认为是与 unsigned char 不同的类型和 signed char .所以只需调用 frobnicate<char>()无法编译,因为它不会选择任何专门的 FrobnicationTraits。
我可以手动添加一个专业:

template<>
struct FrobnicationTraits<char>
{
static constexpr bool isValidFrobnicationType = true;
static constexpr bool isUnsigned = true;
static constexpr char minValue = 0;
static constexpr char maxValue = 255;
};

但我无法提前知道这是否正确。事实上,我碰巧选择了错误的值,所以这会打印“Frobnicating with unsigned type of size 1 between 0 and -1”。

我想有效地做到这一点:

template<> // I don't know where to put the `std::enable_if<>` here, but use this if char is unsigned
struct FrobnicationTraits<char>
{
static constexpr bool isValidFrobnicationType = true;
static constexpr bool isUnsigned = true;
static constexpr char minValue = 0;
static constexpr char maxValue = 255;
};

template<> // I don't know where to put the `std::enable_if<>` here, but use this if char is signed
struct FrobnicationTraits<char>
{
static constexpr bool isValidFrobnicationType = true;
static constexpr bool isUnsigned = false;
static constexpr char minValue = -128;
static constexpr char maxValue = 127;
};

理想情况下,解决方案不应使用预处理器。

最佳答案

std::is_signed 可以告诉你char签名与否。如果不需要区分charsigned char/unsigned char您可以通过 std::conditional 从其中任何一个继承来重用这些特征:

template<>
struct FrobnicationTraits<char> : FrobnicationTraits<
std::conditional_t<
std::is_signed_v<char>,
signed char,
unsigned char
>
>
{};

也许使用帮助器:

using signed_or_unsigned_char = std::conditional_t<std::is_signed_v<char>,signed char, unsigned char>;

然后继承FrobnicationTraits<char>来自 FrobnicationTraits<signed_or_unsigned_char> .

PS:请注意, std::numerical_limits 已经涵盖了您的一些特征功能。 .如果您使用 std::is_signed直接来说,你在 trait 中真正需要的只是 isValidFrobnicationType .

关于c++ - 依赖于 char 符号的专用结构模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71839894/

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