标签: c++-concepts

C++ 0x概念和Boost概念检查库(BCCL)之间有什么区别?

概念没有制定C++ 0x标准,但Boost仍然提供了Boost概念检查库(BCCL).我想BCCL并未涵盖C++ 0x标准的所有内容.BCCL和提议的C++ 0x解决方案有什么区别?

c++ boost c++11 c++-concepts

19
推荐指数
1
解决办法
4007
查看次数

什么是概念演员的等价物?

考虑class A满足两个概念ConceptAConceptB.让一个函数foo重载两个概念:

void foo(ConceptA& arg);
void foo(ConceptB& arg);
A a;
fun(concept_cast<ConceptA>(a));
Run Code Online (Sandbox Code Playgroud)

注意:此示例使用作为N3701,§5的一部分提出的"Terse Notation"语法

是否存在concept_cast允许用户选择重载的东西?

例如:可以说, ConceptA说T有权有一个成员函数bar() ConceptB说T有权有一个成员函数baz() ,并class A同时具有bar()baz()成员函数

它显然是模棱两可的,但有没有办法明确选择我们static_cast正常的重载?

更新:已接受的答案超过2年.c ++ 17中的任何更新?

c++ c++-concepts c++17

19
推荐指数
1
解决办法
399
查看次数

使用 C++20 概念为自定义容器创建迭代器

C++20 引入了概念,这是一种对模板函数或类可以采用的类型施加约束的智能方法。

虽然迭代器类别和属性保持不变,但改变的是执行它们的方式:C++17 之前使用标记,C++20 以来使用概念。例如,您可以使用 std::forward_iterator 概念来标记迭代器,而不是使用 std::forward_iterator_tag 标签。

同样的事情也适用于所有迭代器属性。例如,前向迭代器必须是 std::incrementable。这种新机制有助于获得更好的迭代器定义,并使编译器中的错误更具可读性。

这段文字摘自这篇文章: https ://www.internalpointers.com/post/writing-custom-iterators-modern-cpp

但作者并没有升级如何用概念在C++20上制作自定义迭代器的内容,仍然是<= C++17标签版本。

有人可以举例说明如何使用概念功能在 C++20 版本中为自定义容器编写自定义迭代器吗?

c++ c++-concepts c++20

19
推荐指数
1
解决办法
5417
查看次数

为什么不同的编译器对这些 require 表达式的行为不同?

为什么 C++ 20 中使用 require 表达式的“Oneable”概念的某些实现无法在某些编译器上编译?

// `Oneable` implemented using `requires` with a simple assignment expression

// clang, gcc, and msvc all compile

template <class T>
concept Oneable = requires(T n) { n = 1; };

static_assert(Oneable<int>);
static_assert(!Oneable<int*>);
Run Code Online (Sandbox Code Playgroud)
// `Oneable` implemented using `requires` with an assignment statement inside
// the body of a lambda expression

// clang and msvc compile
// gcc gives a compiler error on instantiating Oneable<T*>

template <class T>
concept Oneable = requires { []() { T …
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++20

19
推荐指数
1
解决办法
1281
查看次数

C++20 概念:如何在`requires` 子句中引用类名?

我有一个 CRTP 课程

template <typename T>
class Wrapper
{
  // ...
};
Run Code Online (Sandbox Code Playgroud)

旨在导出为

class Type : Wrapper<Type>
{
  // ...
};
Run Code Online (Sandbox Code Playgroud)

我想通过对模板参数施加约束来强制执行T。有一个friend技巧可以做到这一点,但我认为在概念时代应该有更好的方法。我的第一次尝试是

#include <concepts>

template <typename T>
  requires std::derived_from<T, Wrapper<T>>
class Wrapper
{
  // ...
};
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为我指的是Wrapper在声明之前。我发现了一些不完全令人满意的解决方法。我可以将约束添加到构造函数

Wrapper() requires std::derived_from<T, Wrapper<T>>;
Run Code Online (Sandbox Code Playgroud)

但是如果我有更多的构造函数也必须受到约束,这就不方便了。我可以用析构函数来做

~Wrapper() requires std::derived_from<T, Wrapper<T>> = default;
Run Code Online (Sandbox Code Playgroud)

但是声明析构函数只是为了穿上它感觉有点傻requires

我想知道是否有更好,更惯用的方法来做到这一点。特别是,虽然这些方法似乎有效(在 gcc 10 上测试过),但一件令人不满意的事情是,如果我Type从派生Wrapper<OtherType>,那么只有在我实例化 时才会引发错误Type。是否有可能在定义点出现错误Type

c++ c++-concepts

18
推荐指数
1
解决办法
255
查看次数

为什么 std::derived_from 概念是通过添加 cv 限定符的附加可转换性测试来实现的?

在 GCC C++20 概念库中,它有

template<typename _Derived, typename _Base>
    concept derived_from = __is_base_of(_Base, _Derived)
    && is_convertible_v<const volatile _Derived*, const volatile _Base*>;
Run Code Online (Sandbox Code Playgroud)
  1. 为什么要求__is_base_of(_Base, _Derived)不够?
  2. const volatile测试中需要用到什么?

c++ libstdc++ c++-concepts c++20

18
推荐指数
2
解决办法
679
查看次数

C++20 中概念化的“operator auto”

从 C++20 开始,我们可以在auto关键字前面加上概念的名称来限制可能的类型。特别是这种组合在类转换中是可能的operator auto,例如

template <typename T> concept x = true;

struct S
{
    operator x auto() { return 2; }
    operator auto() { return 1; }
};

int main() { return S{}.operator x auto(); }
Run Code Online (Sandbox Code Playgroud)

但是 Clang 是唯一接受整个程序的编译器,但是main()返回1(而不是2我预期的那样),演示:https : //gcc.godbolt.org/z/b16jYGa81

GCC 接受结构体定义,但拒绝编译S{}.operator x auto().

即使struct S出现错误,MSVC 也拒绝接受:

error C2535: 'S::operator auto(void)': member function already defined or declared
Run Code Online (Sandbox Code Playgroud)

只是想知道,哪个编译器就在这里(如果有的话)?

c++ auto c++-concepts c++20

18
推荐指数
1
解决办法
612
查看次数

模板约束与成员函数约束的功能等效性

最新的标准草案N4910在 [temp.over.link] 中有关于功能等效性的示例

template<int I> concept C = true;
template<typename T> struct A {
void f() requires C<42>; // #1
void f() requires true; // OK, different functions
};
Run Code Online (Sandbox Code Playgroud)

我的理解是,这没问题,因为C<42>true是未评估的操作数。因此,根据[temp.over.link]/5,在考虑约束是否在功能上等价时,不是表达式的结果,而是对哪个实体执行什么操作以及以什么顺序执行,才是决定约束功能等价的。

但是,如果约束在功能上等效,那么由于它们不等效,根据[temp.over.link]/7,程序将格式错误,无需诊断,因为两次声明同一成员将使程序格式错误。

另一方面

template<typename>
requires C<42>
void g() {};

template<typename>
requires true
void g() {};
Run Code Online (Sandbox Code Playgroud)

似乎格式不正确,不需要诊断,因为[temp.over.link]/6表示如果模板头接受并满足相同的模板参数,则它们在功能上是等效的。

我是否误解了示例并引用了标准措辞,或者真的有这样的差异吗?如果是这样,为什么?

c++ language-lawyer c++-concepts c++23

18
推荐指数
1
解决办法
500
查看次数

如何将模板参数包参数限制为“链”序列?

假设我有两个课程:

\n
template <typename X, typename Y>\nclass Functor {};\n\ntemplate <typename Start, typename End, typename ...Functors>\nclass Template {};\n
Run Code Online (Sandbox Code Playgroud)\n

Template有以下限制:

\n
    \n
  • 全部Functors必须是类型Functor

    \n
  • \n
  • 所有内容都Functor必须按链式顺序排列,这样

    \n
      \n
    • 一个 Functor必须Start作为其第一个参数
    • \n
    • 最后 一个Functor必须End作为第二个参数
    • \n
    • 每个Functor\ 的第一个参数是前面它的第二个参数Functor
    • \n
    \n

    例如Functor<A,B>, Functor<B, C>, Functor<C, D>, ...等等。

    \n
  • \n
\n

例子:

\n

从...开始:char

\n

结尾为: …

c++ templates template-meta-programming c++-concepts c++20

18
推荐指数
3
解决办法
2218
查看次数

使用带有 c++20 概念的 clang-format

我查看了 clang-format 样式选项https://clang.llvm.org/docs/ClangFormatStyleOptions.html但没有看到任何对 c++ 概念和需要子句的引用。通常我可以配置 clang-format 来做我想做的事,但我不知道如何让它很好地处理我的概念和需要条款:

  1. 目前 clang-format 对我的概念做了这个:
template <typename F, typename P, typename T>
concept Accumulate_Fn = Parser<P>&& std::invocable<F, T, parser_t<P>>&&
    std::same_as<T, std::invoke_result_t<F, T, parser_t<P>>>;
Run Code Online (Sandbox Code Playgroud)

但是我想将每个约束放在自己的行上(就像它处理太长的函数参数一样),以便结果如下所示:

template <typename F, typename P, typename T>
concept Accumulate_Fn = Parser<P> &&
                        std::invocable<F, T, parser_t<P>> &&
                        std::same_as<T, std::invoke_result_t<F, T, parser_t<P>>>;
Run Code Online (Sandbox Code Playgroud)
  1. 对于带有 requires 子句的函数,clang-format 目前给了我:
template <Parser P1, Parser P2, typename T, Accumulate_Fn<P1, parser_t<P1>> F>
requires std::same_as<T, parser_t<P1>> constexpr Parser auto
separated_by(P1&& p1, P2&& p2, T&& init, F&& f)
Run Code Online (Sandbox Code Playgroud)

但我想要更接近的东西: …

c++-concepts clang-format c++20

17
推荐指数
1
解决办法
1286
查看次数