专用于 std 元组的模板,而无需用户执行remove_cvref
Specializing a template for std tuple without requiring users to do remove_cvref
你可能知道,因为C++不支持类型列表,除非在特殊情况下,大多数人只是使用元组作为丑陋的类型列表。 因此,例如,要检查某些列表是否仅包含 fp 数字,可以这样做:
template <typename T>
struct AllFp {};
template <typename... T>
struct AllFp<std::tuple<T...>> {
static constexpr bool value =
(std::is_floating_point_v<std::remove_cvref_t<T>> && ...);
};
虽然这似乎有效,但如果用户传递 const std::tuple 或对元组的引用,它实际上不起作用。
#include<type_traits>
#include<tuple>
template <typename T>
struct AllFp {};
template <typename... T>
struct AllFp<std::tuple<T...>> {
static constexpr bool value =
(std::is_floating_point_v<std::remove_cvref_t<T>> && ...);
};
int main(){
static_assert(!AllFp<std::tuple<float, int, float>>::value);
static_assert(AllFp<std::tuple<float, long double, float>>::value);
// requires std::remove_cvref_t
//static_assert(AllFp<const std::tuple<float, long double, float>>::value);
//static_assert(AllFp<std::tuple<float, long double, float>&>::value);
}
有没有办法编写模板,以便"用户"(使用 AllFp 的人(不需要清理他们传递的元组类型?
注意:标记C++20,因为我对概念解决方案没问题。
使用 Boost.Mp11,这是一个简短的单行代码(一如既往(:
template <typename L>
using AllFp = mp_all_of<std::remove_cvref_t<L>, std::is_floating_point>;
请注意,std::remove_cvref_t
实际上是C++20。对于早期标准,您可以只执行std::remove_cv_t<std::remove_reference_t<L>>
或仅std::decay_t<L>
以简洁起见。
使用更正的谓词:
template <typename T>
using decays_to_fp = std::is_floating_point<std::remove_cvref_t<T>>;
template <typename L>
using AllFp = mp_all_of<std::remove_cvref_t<L>, decays_to_fp>;
或:
template <typename L>
using AllFp = mp_all_of_q<std::remove_cvref_t<L>,
mp_compose<std::remove_cvref_t, std::is_floating_point>>;
您所需要的只是额外的间接级别。将主模板和专用化从AllFp
重命名为AllFp_Impl
。然后AllFp
创建一个别名模板,该模板负责从tuple
本身中删除 cvref 限定:
template <typename T>
using AllFp = AllFp_Impl<std::remove_cvref_t<T>>;
这是一个演示。
您还可以使用一种自我继承。
我的意思是:您可以添加以下专业
template <typename T>
struct AllFp<T const> : public AllFp<T>
{ };
template <typename T>
struct AllFp<T&> : public AllFp<T>
{ };
下面是一个仅使用std::remove_cv_t
的完整编译(static_assert()
没有错误(示例
#include<type_traits>
#include<tuple>
template <typename T>
struct AllFp {};
template <typename T>
struct AllFp<T const> : public AllFp<T>
{ };
template <typename T>
struct AllFp<T&> : public AllFp<T>
{ };
template <typename... T>
struct AllFp<std::tuple<T...>> {
static constexpr bool value =
(std::is_floating_point_v<std::remove_cv_t<T>> && ...);
};
int main(){
static_assert(!AllFp<std::tuple<float, int, float>>::value);
static_assert(AllFp<std::tuple<float, long double, float>>::value);
static_assert(AllFp<const std::tuple<float, long double, float>>::value);
static_assert(AllFp<std::tuple<float, long double, float>&>::value);
}
相关文章:
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 专用于 std 元组的模板,而无需用户执行remove_cvref
- 在 C++ Consol 中的数组中执行用户命令时出现问题
- 代码在执行之前终止,并且没有从用户那里获取输入
- C++ - 使用用户输入的字符串数据检查结构字符串数据(无限执行 while 循环)
- Win7 C++ - 从以用户身份登录的服务启动可执行文件的问题
- 为什么在代码块中执行时会跳过输入用户输入的行?
- 以普通用户身份执行命令
- 如何在函数中暂停程序,直到用户在窗体上执行某些操作
- 我想制作一个程序来执行一些用户制作的功能,例如加法和其他东西
- 为可执行文件授予比运行用户更多的权限
- 如何使用我的 if-else 语句根据用户权重的输入执行特定操作,然后将其显示到控制台?
- 确定QProcess是否已完成执行或正在等待用户输入(或响应)
- 如何在C 中的用户提交变量列表中执行多个操作
- 当两个用户定义的复制构造函数时,是否有任何方法可以执行复制构造函数
- 需要接受用户的响应才能执行程序
- 使用用户定义的函数对循环/对称值执行Sqlite(C API)和查询(选择)
- 程序在用户的第一个输入时不执行任何操作(跳过程序中的整个代码)
- 当用户将列表视图项拖动到其滚动条上时,执行默认滚动行为
- 想要用cuda内核执行一个循环直到用户取消