表示"accepting anything for this template argument" C++概念的通配符
Wildcard for C++ concepts saying "accepting anything for this template argument"
是否有方法允许具有模板参数的concept
可以使用所提供的任何模板参数?
例如,模板参数占位符的某种通配符魔术?
用法示例:
template<class Me, class TestAgainst>
concept derived_from_or_same_as =
std::same_as<Me, TestAgainst> ||
std::derived_from<Me, TestAgainst>;
需要以上内容,因为不幸的是,对于 类类型现在,我们可以定义一个对 用例[a]-接受任何有效的As对或As的子类型: 用例[b]-接受任何有效的对,对内部类型没有限制: 遗憾的是,在C++20中,auto不允许作为模板参数占位符。 因此 其他语言在某种程度上允许这样的语法,尽管与这里要求的语义和含义不同,但用法看起来非常相似。 Python: Java: C++20之前的语法看起来像1: 用例[a]-尝试接受任何有效的As对或As的子类型: 用例[b]-接受任何有效的对,对内部类型没有限制: C++20之前的代码 概念能否提供更好的解决方案 1关于模板的相关问题(C++20之前(:模板在C++中接受"任何东西">is_base_of
和derived_from
,基元类型的行为与concept
,用于检查提供的类型:template<class P, class First, class Second>
concept Pair = requires(P p) {
requires derived_from_or_same_as<decltype(p.first), First>;
requires derived_from_or_same_as<decltype(p.second), Second>;
};
// this works well
void doWithPairOfA(const Pair<A, A> auto& p) { /* */ }
// this is *pseudo code* as Pair<auto, auto> is not allowed
void doWithAnyPair(const Pair<auto, auto> auto& p) { /* */ }
Pair<auto, auto>
目前不是解决方案。// Any as wildcard
foo(lst: List[Any]) -> List[str]
// '?' as wildcard
List<String> foo(List<?> lst)
// not as good as with concepts above, this allows only "pair" of A and A
// **but rejects sub-types of A, which is not good**
// and there is no check that this is actually a pair (can be added with SFINAE)
template<template<class, class> typename PAIR>
void doWithPairOfA(const PAIR<A, A>& p) { /* */ }
// not as good as we would wish - we do allow any kind of "pair"
// but there is no check that this is actually a pair (can be added with SFINAE)
template<template<class, class> typename PAIR, typename ANY1, typename ANY2>
void doWithAnyPair(const PAIR<ANY1, ANY2>& p) { /* */ }
您可以通过修改对concept
以接受和检查标签类型Any来实现通配符行为。
让我们首先将Any声明为标记类,无需实现它
class Any;
现在,我们可以创建type_matchesconcept
来检查类型T是否与给定类型a匹配,规则如下:
T匹配A
- 如果A是任何--或--
- 如果T=A,或者如果T是从A导出的
如问题中所述,对T=A或T的检查是从派生的。可以仅使用std::derived_from
对类类型进行检查,但是基元类型需要添加std::same_as
的测试。
通配符匹配将使用以下代码实现:
template<class Me, class TestAgainst>
concept type_matches =
std::same_as<TestAgainst, Any> ||
std::same_as<Me, TestAgainst> ||
std::derived_from<Me, TestAgainst>;
配对概念将修改为:
template<class P, class First, class Second>
concept Pair = requires(P p) {
requires type_matches<decltype(p.first), First>;
requires type_matches<decltype(p.second), Second>;
};
该代码现在可以允许两种所需的用例。
用例[a]-接受任何有效的As对或As的子类型:
// can be called with a Pair of As or sub-type of As
void doWithPairOfA(const Pair<A, A> auto& p) { /* */ }
用例[b]-接受任何有效的对,对内部类型没有限制:
void doWithAnyPair(const Pair<Any, Any> auto& p) { /* */ }
代码:https://godbolt.org/z/higX9f
- 表示"accepting anything for this template argument" C++概念的通配符
- 当使用通配符和null指针调用函数时,对输出的说明
- C++17 文件系统::remove_all 带有通配符路径
- 如何允许通配符模板参数
- 使用通配符的跨平台文件列表
- 如何检索由带通配符的字符串索引的对象
- 有效地查找通配符条目
- 具有不同输入和输出名称的生成文件通配符
- MinGW GCC通配符编译所有文件(Windows)
- Windows 上带有通配符的目录中的文件
- 查找第一个文件W通配符匹配
- 在某些情况下,通配符模式匹配失败
- 实现通配符后没有输入文件错误
- 如何为文件对话框过滤器设置通配符
- 使用通配符搜索QTableWidget时出现问题
- 为什么 std::experimental::filesystem::p ath 不接受像 "*" 这样的通配符?
- 在三元搜索树中搜索(NOT with)通配符
- SQLite如何在列上使用LIKE并添加通配符
- 带有通配符的 ifstream
- 有什么方法可以在C #include语句中使用通配符