标签: c++-concepts

为什么我不能在类范围内声明一个概念?

考虑这个代码:

struct A
{
    template <typename T>
    concept foo = true;
};
Run Code Online (Sandbox Code Playgroud)

它不编译。我的 Clang 10 给了我error: concept declarations may only appear in global or namespace scope,GCC 说了类似的话。

有理由不允许吗?我不明白为什么它不能工作,即使封闭类是一个模板。

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

23
推荐指数
1
解决办法
1061
查看次数

如何使用 C++ 20 要求/概念限制折叠表达式?

如何使用 C++20 概念限制可变参数模板和折叠表达式中允许的类型?

例如,假设我想限制以下折叠表达式仅支持整数类型,我该怎么做?

#include <string>
#include <iostream>
#include <concepts>
using namespace std;

template<typename... Args> // requires (is_integral<Args>::value )
    int sum(Args... args) { return (... + args); }
int main()
{
    cout << sum(1,2,3);
}
Run Code Online (Sandbox Code Playgroud)

c++ variadic-templates c++-concepts fold-expression c++20

23
推荐指数
2
解决办法
1887
查看次数

概念与接口有何不同?

概念(即最近从C++ 0x标准中删除的那些)与Java等语言中的接口有何不同?

c++ generics templates c++11 c++-concepts

22
推荐指数
2
解决办法
2787
查看次数

什么是概念?

我已经听说所有这些关于C++ 0x的新的(on /.)不再有概念,但我不知道它们是什么?有人可以向我解释一下吗?

c++ generic-programming c++11 c++-concepts

22
推荐指数
2
解决办法
1075
查看次数

带有多个模板参数的C++概念

Bjarne Stroustrup最近发表了一篇关于C++ Concepts 的报告,他提到了一些让我感到惊讶的事情.示例(在第7.1节中)使用"简写模板表示法",基本上是这样的:

void foo1(auto x,auto y);                // x and y may have different types  (1)
void foo2(SomeConcept x,SomeConcept y);  // x and y must have the same type   (2)
Run Code Online (Sandbox Code Playgroud)

就我个人而言,这似乎非常违反直觉; 事实上,我希望foo2接受不同类型的值x,y,只要各个类型满足SomeConcept.请注意,程序员始终可以通过编写以下内容之一来明确指定其意图:

template <SomeConcept T> void foo2(T x, T y);                   // (3)
template <SomeConcept T1,SomeConcept T2> void foo2(T1 x,T2 y);  // (4)
Run Code Online (Sandbox Code Playgroud)

直觉上,我希望(2)中的简写符号等同于(4),因此更符合无约束模板(1)的含义.有人可以解释这个问题并解释这个设计决定背后的理由吗?

一些评论:

  • afaik,generic lambdas(在C++ 14中)已经允许类似于(1)的语法.因此,一致性要求(1)应该接受具有不同类型的输入变量,因为通用lambda就是这样做的.
  • Stroustrup在这种模板的上下文中提到了经典的"迭代器对".但是,我认为这是一个相当弱的论据,因为(i)这只是一个用例和(ii)afaik,C++ 17引入(迭代器,哨兵)对,这迫使通用代码使用两种不同的类型.

c++ templates c++-concepts

22
推荐指数
1
解决办法
774
查看次数

为什么在概念中使用std :: forward?

我正在阅读Constraints上cppreference页面并注意到这个例子:

// example constraint from the standard library (ranges TS)
template <class T, class U = T>
concept bool Swappable = requires(T t, U u) {
    swap(std::forward<T>(t), std::forward<U>(u));
    swap(std::forward<U>(u), std::forward<T>(t));
};
Run Code Online (Sandbox Code Playgroud)

我很困惑他们为什么要用std::forward.有些人试图在模板参数中支持引用类型吗?我们不想swapforward左值调用,并且当标量(非参考)类型时T,表达式不是rvalues U吗?

例如,我希望这个程序在Swappable实现时失败:

#include <utility>

// example constraint from the standard library (ranges TS)
template <class T, class U = T>
concept bool Swappable = requires(T t, U u) {
    swap(std::forward<T>(t), std::forward<U>(u));
    swap(std::forward<U>(u), std::forward<T>(t)); …
Run Code Online (Sandbox Code Playgroud)

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

22
推荐指数
1
解决办法
484
查看次数

只有布尔文字值的概念是格式错误的,不需要诊断吗?

我在完全从任何模板中删除的上下文中玩弄 C++ 概念和函数重载,并偶然发现了这一点:

struct S
{
    int mult(int x) requires (true)  { return x; }
    int mult(int x) requires (false) { return x * 2; }
};

int main()
{
    std::cout << S{}.mult(5) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

g++ 11 拒绝编译此代码段,因为requires-clauses 可能不会附加到非模板函数。

然而,clang++ 13 对这个代码段很好,但令人惊讶的是它吐出10而不是5我所期望的。

我知道 C++20 标准最近才出炉,所以我完全理解关于概念有很多问题需要解决。

忽略常量字面概念的明显无用,我的问题是:带有 -requires子句的程序是否总是格式错误的false,可能不需要诊断?或者,也许,正如 g++ 所说,我什至根本没有合法的 C++?

c++ language-lawyer c++-concepts c++20

22
推荐指数
2
解决办法
923
查看次数

如何通过自定义错误消息使概念失败 (C++20)

概念非常擅长将错误定位到“不满足约束”的代码行。

但是,我想知道是否可以在那里发布自定义信息消息。static_assert 的好处就是这种可能性。用例:任何想要帮助用户找出某个表达式不满足约束的原因的库。

这是一个简单的例子,只是为了有一些代码。您可能会争辩说,任何体面的“用户”都必须能够弄清楚编译器的注释“因为 'is_base_of<Base, C>' 评估为 false”,但更多的自定义信息不会受到伤害。肯定会有更复杂的概念。


template<typename B, typename D> 
concept is_base_of = std::is_base_of_v<B, D>;

template <typename T, is_base_of<T> BaseType>
struct BaseWrapper { };  

int main() 
{
    class Base {};
    class Derived : public Base {};
    class C {};

    using T1 = BaseWrapper<Derived,Base>;
    using T2 = BaseWrapper<C,Base>;         // fails right here, but a custom message would be nice
}

Run Code Online (Sandbox Code Playgroud)

c++ templates compiler-errors c++-concepts c++20

21
推荐指数
1
解决办法
790
查看次数

C ++ 20:多种类型的概念及其约束,正确的语法?

可以肯定的是c++20,根据即将到来的标准,根据最近的科隆ISO C ++会议的一份Reddit报告,我们将能够指定模板的概念,并且对于每个类/功能模板,我们将能够设置其类型的约束。 。但是,在文档和教程中(例如here),我找不到适用于多类型用例的正确语法。


假设我们有一个多类型的概念:

template<typename T1, typename T2>
concept AreEqComparable = requires(T1 a, T2 b) {
    { a == b } -> bool;
};
Run Code Online (Sandbox Code Playgroud)

假设我想在两个不同类型之间定义一个简单的比较函数。我怎样才能做到这一点?更具体地说,我应该在???下面的代码部分中写什么:

???
bool are_equal(T1 a, T2 b) { return a == b; }
Run Code Online (Sandbox Code Playgroud)

我在这里这里,甚至这里都没有找到关于这个案例的参考。我已经随机尝试过类似的东西:

/* 1 */ template<AreEqComparable T1, T2>
/* 2 */ AreEqComparable<T1, T2>
/* 3 */ template<AreEqComparable<T1, T2>>
Run Code Online (Sandbox Code Playgroud)

但是所有这些都引发语法错误。我认为答案应该在Bjarne Stroustrup的规范 …

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

20
推荐指数
3
解决办法
1110
查看次数

`equality_comparable_with` 是否需要要求 `common_reference`?

概念equality_­comparable_with<T, U>旨在声明类型T和 的对象U可以相互比较,如果它们是,则这具有预期的含义。没关系。

但是,这个概念也需要common_reference_t<T&, U&>存在。其主要推动力common_reference及其伴随的功能似乎是启用代理迭代器,有一个地方来表示此类迭代器之间的关系reference以及value_type此类迭代器的关系。

太好了,但是……这与测试 aT和 a 是否U可以相等有什么关系?为什么标准要求这样做T并且U有一个共同的参考关系只是为了让你比较它们相等?

这会产生奇怪的情况,其中很难有两种类型没有合理地具有逻辑可比性的公共引用关系。例如,vector<int>pmr::vector<int>逻辑上应该是可比的。但它们不可能,因为这两种不相关的类型之间没有合理的公共引用。

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

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