c++ - 类型特征是否可以限制为不接受其他类型特征作为参数?
问题描述
问题可能很奇怪,所以这里有一个简短的激励示例:
#include <vector>
#include <type_traits>
template <typename T>
// workaround for gcc 8.3 where volatile int is not trivially copyable
using is_tc = std::is_trivially_copyable<std::remove_cv<T>>;
// static assert passes compile, oops
static_assert(is_tc<std::vector<int>>::value);
如您所见,错误是我已将类型特征本身传递给另一个类型特征,而不是传递::type
或使用std::remove_cv_t
.
明显的解决方案是让我不要犯错误,但我想知道 C++ 类型特征是否有办法限制它们的输入类型,以便它们不接受其他 type_traits 作为参数。现在困难的是在 type_traits 中有大量类型特征,所以 IDK 如何最好地实现它。
注意:我不是说 C++ 应该这样做,我知道防止罕见错误需要做很多工作,我只是想了解更复杂的概念设计,其中您的限制不是基于类型的语义(也就是 ++和 *) 但事实上类型属于大量类型(并且该集合包括您限制的类型)。
解决方案
好吧,假设您在可能的情况下总是需要::type
as 参数,这里有一个快速的解决方法:
template<class T> concept HasType = requires { typename T::type; };
template<class T> concept HasNoType = !HasType<T>;
template<HasNoType T> using remove_cv = std::remove_cv<T>;
template<HasNoType T> using remove_cv_t = typename remove_cv<T>::type;
除了修补 STL 标头或子类化 STL 类型(并非总是允许)之外,您无法重新定义预定义的内容。
您的限制不是基于类型的语义(又名具有 ++ 和 *),而是基于类型属于大量类型的事实
无论发生什么,您都需要一个谓词来指定这个集合(∊S
给定 S 的运算符)。例如has ++
,与其他任何谓词一样好。
谓词可以用更多级别的间接和一些样板来细化,比如说
template<class T> struct not_a_type_trait =
std::integral_constant<bool, HasNoType<T>> {};
template<class T> inline constexpr not_a_type_trait_v = not_a_type_trait<T>::value;
template<class T> concept NotATrait = not_a_type_trait_v<T>;
struct AnArg { using type = void; };
template<> struct not_a_type_trait<AnArg>: std::true_type {};
// now can be an arg to remove_cv
或者,在这种特殊情况下,您可以简单地将所有 STL 的特征列入黑名单,但这将是一个非常大的谓词,需要随着每个标准版本的更新而更新。
推荐阅读
- html - html css 格式的反增量
- python - 将 Pix2Pix 生成器导出到 tflite 模型
- python - 用熊猫连续计算天气高于特定温度的天数
- javascript - 如何将 Promise 值传递给某个单独的函数?- JavaScript
- python - Pyspark:如何从另一个数据帧向数据帧添加列?
- spring - 春季靴子遵循哪个最佳标准?
- javascript - 运行长时间运行的进程时,Socket.io(使用flask和javascript)连接断开
- sql - 如何在 postgresql/timescaledb 中以编程方式调用“刷新物化视图”
- php - laravel 403此操作未经授权
- php - Laravel 网站没有在子文件夹中显示内容?