我正试图弄清楚如何编写一个检查变量模板中没有重复类型的conecpt。
我知道我不能递归地调用一个概念本身,但如果我可以,我的解决方案会看起来像这样(忽略缺少停止条件):
#include <concepts>
template <class TYPE, class ... TYPE_LIST>
concept is_not_in_list = ((!std::same_as<TYPE, TYPE_LIST>) && ...);
template <class FIRST_TYPE_IN_LIST, class ... REST_OF_TYPE_LIST>
concept is_non_repeating_list_ = (_type_not_in_list_<FIRST_TYPE_IN_LIST, REST_OF_TYPE_LIST> && is_non_repeating_list<REST_OF_TYPE_LIST>);
// Usage
template<is_non_repeating_list ... TYPE_LIST>
class MyClass {}
我在标准库中找不到类型特征或概念来帮助我解决这个问题。有什么想法吗?
5条答案
按热度按时间dgiusagp1#
这似乎是工作(live demo):
2mbi3lxu2#
这种疯狂的结构解决了递归问题。
但也没什么用因为
不像
is_non_repeating_list<TYPE_LIST...>
那样将TYPE_LIST
传递给is_non_repeating_list
,而是像is_non_repeating_list<TYPE_LIST>...
那样。也就是说,每个
is_non_repeating_list
从您测试的TYPE_LIST
中获得 * 确切的一个 * 类型。你能做到的
但是。
nuypyhwy3#
下面是一个使用fold表达式的非递归实现:
这包括其他几个有用的实用程序,包括
type_list
,这是STL中缺少的。dba5bblo4#
一种非标准的方法是先对convert each type to a string,然后应用相应的算法进行检查
x4shl7ld5#
大多数解决这个问题的方法都不能很好地扩展类型列表的长度--编译时间将是二次的,甚至更糟,天真地遍历包而不是使用折叠表达式很容易在包的长度上是三次的。
这里有一种在编译时只在包长度上线性增长的方法,假设
std::make_index_sequence<N>
在N
中是最差的线性:这里的技巧是
indexed_types
是一个标准布局的类类型,当且仅当它的所有基类都是不同的类型,当且仅当类型包不包含重复的类型时,才会发生这种情况。索引序列和额外的基类层只是为了避免indexed_types
包含重复的直接基类,这将是病态的。