C++ C++;20个概念:多重返回类型要求?

C++ C++;20个概念:多重返回类型要求?,c++,c++20,c++-concepts,C++,C++20,C++ Concepts,我想实现一个概念,其中有多个成员函数的返回类型 例: 模板 概念容器=需要(C a){ {a.begin()}-> 标准::与|| 标准::与标准相同; }; 上面的代码是为了强制执行a.begin()的返回类型为C::iterator或C::const\u iterator 但它不编译 还有其他方法吗?使用不加修饰的表单 template<typename C> concept Container = requires(C a) { requires std::same_

我想实现一个
概念
,其中有多个成员函数的返回类型

例:

模板
概念容器=需要(C a){
{a.begin()}->
标准::与||
标准::与标准相同;
};
上面的代码是为了强制执行
a.begin()
的返回类型为
C::iterator
C::const\u iterator

但它不编译


还有其他方法吗?

使用不加修饰的表单

template<typename C>
concept Container = requires(C a) {
    requires std::same_as<decltype(a.begin()), typename C::iterator> ||
      std::same_as<decltype(a.begin()), typename C::const_iterator>;
};
模板
概念容器=需要(C a){
需要std::与相同的_||
标准::与标准相同;
};

使用未加修饰的表单

template<typename C>
concept Container = requires(C a) {
    requires std::same_as<decltype(a.begin()), typename C::iterator> ||
      std::same_as<decltype(a.begin()), typename C::const_iterator>;
};
模板
概念容器=需要(C a){
需要std::与相同的_||
标准::与标准相同;
};

您可以编写一个概念来测试该类型是否为容器的迭代器类型之一:

template<typename It, typename Container>
concept is_container_iterator =
    same_as<It, typename Container::iterator> || same_as<It, typename Container::const_iterator>;
模板
概念是容器迭代器=
与…相同;与…相同;

然后可以在代码中使用该概念:
{a.begin()}->is\u container\u迭代器

您可以编写一个概念来测试该类型是否为容器的迭代器类型之一:

template<typename It, typename Container>
concept is_container_iterator =
    same_as<It, typename Container::iterator> || same_as<It, typename Container::const_iterator>;
模板
概念是容器迭代器=
与…相同;与…相同;

然后可以在代码中使用该概念:
{a.begin()}->is\u container\u迭代器

这是否回答了您的问题@康桓瑋 不,我正在实现的一个并不约束多个概念。CPPNearner展示了这个技巧。对于这个特定的案例,您应该检查它是否返回了一个
迭代器
概念(可能是
前向迭代器
),而不是像这样的特定成员。@Nicolas我指的是这里指定的要求:。我首先约束
C::iterator
C::const_iterator
以满足
LegacyForwardIterator
的概念,然后是我在文章中所述的内容。所以,基本上,我是双向的。@PHD:我的观点是,你不应该像那样复制命名需求的确切形式。事实上,现在,你甚至不应该需要一个成员
begin
函数;而是依赖于
范围::begin
。这是否回答了您的问题@康桓瑋 不,我正在实现的一个并不约束多个概念。CPPNearner展示了这个技巧。对于这个特定的案例,您应该检查它是否返回了一个
迭代器
概念(可能是
前向迭代器
),而不是像这样的特定成员。@Nicolas我指的是这里指定的要求:。我首先约束
C::iterator
C::const_iterator
以满足
LegacyForwardIterator
的概念,然后是我在文章中所述的内容。所以,基本上,我是双向的。@PHD:我的观点是,你不应该像那样复制命名需求的确切形式。事实上,现在,你甚至不应该需要一个成员
begin
函数;而是依赖于
范围::begin