c++ - 在 C++ 中构造一个“is_template_instantiable”类型特征
问题描述
是否可以在 C++ 中构造一个类型特征来检查给定的模板类型是否可以用给定的类型作为模板参数来实例化?如果有可能,怎么做?
例如:
static_assert(is_template_instantiable_v<std::optional, int, int>);
static_assert(is_template_instantiable_v<std::vector, double>);
第一个断言会失败,因为std::optional
只需要一个模板参数。第二个断言没有失败,std::vector
可以只用一个模板参数实例化,因为它的第二个模板参数有一个默认值。
如果上述情况可行,是否可以在以下情况下让类型特征为假(并且不会触发编译错误):
static_assert(is_template_instantiable_v<std::vector, int &>);
因为std::vector
可能不会用引用作为其值类型来实例化。
我的猜测是第一个示例可能可以复制,而仅使用标准 C++ 代码无法完成第二个示例。
解决方案
我假设第一个要求可以通过基于检测习语的方法来实现:
namespace detail
{
template<template<typename...> typename T, typename AlwaysVoid, typename... Ts>
struct is_template_instantiable :
std::false_type {};
template<template<typename...> typename T, typename... Ts>
struct is_template_instantiable<T, std::void_t<T<Ts...>>, Ts...> :
std::true_type {};
template<template<typename...> typename T, typename... Ts>
inline constexpr auto is_template_instantiable_v =
is_template_instantiable<T, void, Ts...>::value;
}
然后,使用:
template<typename T = void>
struct X{};
它产生:
static_assert(detail::is_template_instantiable_v<X>);
static_assert(detail::is_template_instantiable_v<X, void>);
static_assert(!detail::is_template_instantiable_v<X, void, int>);
但是,由于这种类型的特征,我无法解决第二个挑战......
推荐阅读
- excel - 宏 Excel 从各种文件导入单张工作表
- jenkins - 使用提交链接构建作业(不是分支)
- swiftui - 我是否正确对齐了这个 SKLabelNode?
- css - 触发复选框时背景渐变之间的css过渡
- apache-kafka - BATCH vs MANUAL 和 ack vs commit
- xamarin - 如何使用 xamarin.forms、DateTime.Now 显示当前时间而不在 Android 上实时更新?
- linux - 如何在不降低安全性的情况下修复 openssl 问题“tls_process_ske_dhe:dh key too small”
- arrays - swift如何使用范围参数声明函数
- mysql - 在 WAMP 中,您可以将不同的数据库放在不同的驱动器上吗
- javascript - 如何停止表单中包含无效字段的表单提交?