微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C ++中字符类型的类型特征?

如何解决C ++中字符类型的类型特征?

我正在编写一个能够处理任何整数类型的库函数,但我想防止它也处理字符类型(例如 minmax()char 等),因为它可能让用户感到困惑(我有一个单独的函数来处理看起来像字符的字符)。

我目前正在使用这样的代码

char16_t

然而,这似乎很脆弱 - 例如,这在带有 template < typename = std::enable_if_t< std::is_integral_v<T> && !std::is_same_v<std::decay_t<T>,bool> && !std::is_same_v<std::decay_t<T>,char> && !std::is_same_v<std::decay_t<T>,wchar_t> && !std::is_same_v<std::decay_t<T>,char16_t> && !std::is_same_v<std::decay_t<T>,char32_t>>> constexpr auto do_stuff(T curr) noexcept { /* Todo */ } 的 C++20 编译器上并不完全正确,即使我对 char8_t 进行了适当的功能测试,它也是把它们都列出来还是很尴尬。

有没有办法检测类似 char 的类型,而我不需要将它们全部列出来?

解决方法

你可以这样做:

template <
    typename T,std::enable_if_t<std::is_integral_v<T>,std::nullptr_t> = nullptr,std::enable_if_t<std::is_same_v<T,std::make_signed_t<T>> || std::is_same_v<T,std::make_unsigned_t<T>>,std::nullptr_t> = nullptr
>

这接受 signed charunsigned char,同时拒绝 charint8_t 在所有常见的标准库实现(libstdc++、libc++ 和 MSVC 的实现)上是 signed char

注意不寻常的双 SFINAE。这是必要的,因为如果给定非整数类型,std::make_[un]signed 会导致硬错误。


或者,在 C++20 中,您可以检查 std::cmp_equal 是否接受您的类型。它还拒绝 charchar*_t,同时允许 [un]signed char

requires requires{ std::cmp_equal(T{},T{}); }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。