标签: c++-concepts

为什么我们要求要求?

C++ 20概念的一个角落是,在某些情况下你必须编写requires requires.例如,[expr.prim.req]/3中的这个例子:

需要表达也可以在使用需要子句([温度])作为写在模板参数特设约束,如下面的一个的一种方法:

template<typename T>
  requires requires (T x) { x + x; }
    T add(T a, T b) { return a + b; }
Run Code Online (Sandbox Code Playgroud)

第一个需要引入requires子句,第二个需要引入requires-expression.

需要第二个requires关键字的技术原因是什么?为什么我们不能只允许写作:

template<typename T>
  requires (T x) { x + x; }
    T add(T a, T b) { return a + b; }
Run Code Online (Sandbox Code Playgroud)

(注意:请不要回答那个语法requires吧)

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

155
推荐指数
4
解决办法
1万
查看次数

概念和模板约束之间有什么区别?

我想知道C++完整概念提议和模板约束之间的语义差异(例如,Dlang中出现的约束或C++ 1y的新概念 - 精简提议).

什么是能够比模板约束做的完整概念不能做到的?

c++ d c++11 c++-concepts

95
推荐指数
2
解决办法
2万
查看次数

在 C++ 中限制“auto”是否违背了它的目的?

在 C++20 中,我们现在能够将auto关键字限制为仅属于特定类型。因此,如果我有一些如下所示的代码,没有任何限制:

auto something(){
  return 1;
}

int main(){
  const auto x = something();
  return x;
}
Run Code Online (Sandbox Code Playgroud)

这里的变量x被推导为一个int。然而,随着 C++20 的引入,我们现在可以将 约束auto为某种类型,如下所示:

std::integral auto something(){
  return 0;
}

int main(){
  const auto x = something();
  return x;
}
Run Code Online (Sandbox Code Playgroud)

这不是违背了来这里的目的吗auto?如果我真的需要一个std::integral数据类型,我不能完全省略吗auto?我是否完全误解了使用auto

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

72
推荐指数
3
解决办法
7730
查看次数

void_t"可以实现概念"吗?

我正在观看Walter Brown的CppCon2014关于模板元编程的第二部分,在此期间他讨论了他的新颖void_t<>结构的用法.在他的演讲中,Peter Sommerlad问他一个我不太明白的问题.(链接直接转到问题,正在讨论的代码直接发生在那之前)

索默拉德问道

沃尔特,这是否意味着我们现在实际上可以实现概念精简版?

沃尔特回应了什么

哦耶!我已经完成了......它没有完全相同的语法.

我理解这个交换是关于Concepts Lite的.这种模式真的那么多才多艺吗?无论出于何种原因,我都没有看到它.有人可以解释(或描绘)这样的事情会是什么样子?这是关于enable_if和定义特征,还是提问者指的是什么?

void_t模板定义如下:

template<class ...> using void_t = void;
Run Code Online (Sandbox Code Playgroud)

然后他使用它来检测类型语句是否格式正确,使用它来实现is_copy_assignable类型特征:

//helper type
template<class T>
using copy_assignment_t
= decltype(declval<T&>() = declval<T const&>());

//base case template
template<class T, class=void>
struct is_copy_assignable : std::false_type {};

//SFINAE version only for types where copy_assignment_t<T> is well-formed.
template<class T>
struct is_copy_assignable<T, void_t<copy_assignment_t<T>>> 
: std::is_same<copy_assignment_t<T>,T&> {};
Run Code Online (Sandbox Code Playgroud)

由于这个话题,我理解这个例子是如何工作的,但是我没有看到我们如何从这里得到像Concepts Lite这样的东西.

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

68
推荐指数
1
解决办法
7055
查看次数

使用Concepts Lite为具有成员函数模板的类型指定概念

我正在尝试使用Concepts Lite来指定一个概念来约束具有成员函数模板的更高级的kinded类型.但是,我无法在技术规范教程中找到一个处理概念中模板化语句的子句.

这是怎么做到的?

示例:假设我HKT的成员函数模板具有更高的kinded类型F:

template<class T>
struct HKT {
  template<class U> // this looks like e.g. rebind in std::allocators
  auto F(U) -> HKT<U>;
};
Run Code Online (Sandbox Code Playgroud)

现在我想指定一个约束这些更高级的类型的概念:

template <template <class> class HKT, class T>
concept HKTWithTemplateMemberFunctionF {
  return requires(HKT<T> h) { // HKT<T> is a type, h is an object
    // HKT<T> needs to have a member function template that 
    // returns HTK<U> where the type U is to be deduced and
    // it …
Run Code Online (Sandbox Code Playgroud)

c++ higher-kinded-types c++-concepts

61
推荐指数
2
解决办法
1943
查看次数

为什么unique_ptr 在C++20 中不是equality_comparable_with nullptr_t?

使用 C++20'sconcept我注意到这std::unique_ptr似乎无法满足这个std::equality_comparable_with<std::nullptr_t,...>概念。从std::unique_ptr的定义来看,它应该在 C++20 中实现以下内容:

template<class T1, class D1, class T2, class D2>
bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, std::nullptr_t) noexcept;
Run Code Online (Sandbox Code Playgroud)

这个要求应该实现对称比较nullptr——根据我的理解,这足以满足equality_comparable_with.

奇怪的是,这个问题似乎在所有主要编译器上都是一致的。以下代码被 Clang、GCC 和 MSVC 拒绝:

// fails on all three compilers
static_assert(std::equality_comparable_with<std::unique_ptr<int>,std::nullptr_t>);
Run Code Online (Sandbox Code Playgroud)

Try Online

然而,同样的断言与std::shared_ptr被接受:

// succeeds on all three compilers
static_assert(std::equality_comparable_with<std::shared_ptr<int>,std::nullptr_t>);
Run Code Online (Sandbox Code Playgroud)

Try Online

除非我误解了什么,否则这似乎是一个错误。我的问题是这是否是三个编译器实现中的巧合错误,还是 C++20 标准中的缺陷?

注意:如果这恰好是一个缺陷,我会标记这个

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

50
推荐指数
1
解决办法
2136
查看次数

为什么双重否定会改变 C++ 概念的价值?

我的一个朋友向我展示了一个带有概念的 C++20 程序,这让我感到困惑:

struct A { static constexpr bool a = true; };

template <typename T>
concept C = T::a || T::b;

template <typename T>
concept D = !!(T::a || T::b);

static_assert( C<A> );
static_assert( !D<A> );
Run Code Online (Sandbox Code Playgroud)

它被所有编译器接受:https : //gcc.godbolt.org/z/e67qKoqce

这里的概念与概念D相同C,唯一的区别是双重否定运算符!!,乍一看不会改变概念值。仍然对于 struct 来说,A这个概念C是正确的,而这个概念D是错误的。

你能解释一下为什么会这样吗?

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

49
推荐指数
2
解决办法
2231
查看次数

新的迭代器要求

我注意到大多数(如果不是所有)容器现在都需要它们的::iterator类型LegacySomethingIterator而不是SomethingIterator.

例如,std::vector<>::iterator 现在需要:

iterator LegacyRandomAccessIterator

这似乎是大多数其它容器一样,都是需要自己迭代器从去SomethingIteratorLegacySomethingIterator.

还有"新"要求采用旧要求的名称,例如RandomAccessIterator,为什么这些要求被添加?在我看来,新的变种只会影响遗留的变种,没有差异.

为什么首先创建新的,他们的要求对我来说是一样的.为什么新的只是替换旧的要求而不是现在有两个不同的名称(例如RandomAccessIteratorLegacyRandomAccessIterator)?

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

40
推荐指数
1
解决办法
3570
查看次数

如何使用C++概念("concepts lite")支持构建gcc?

C++标准委员会正在研究概念扩展的TS(技术规范):"Programming Languages - C++ Extensions for Concepts".N4377是本文档的最新版本.为了包含在C++标准中,要求实现功能,理想情况是可公开访问的系统.

我知道概念-gcc,但上面的概念提议(通俗地称为Concepts Lite)是不同的.我听说有一个概念的分支,我已经尝试了origin/asutton/c++-conceptsGCCgit镜,但没有编制.如何构建和使用上述[草案] TS中指定的gcc支持概念版本?

c++ g++ generic-programming c++-concepts c++17

39
推荐指数
2
解决办法
7364
查看次数

C ++的概念和Rust的特征之间有什么异同?

在Rust中,抽象的主要工具是traits。在C ++中,有两种用于抽象的工具:抽象类和模板。为了摆脱一些使用模板的缺点(例如,硬盘读取错误消息),C ++引入的概念,这是“命名集的要求”

这两个功能似乎非常相似:

  • 定义特征/概念是通过列出要求来完成的。
  • 两者都可以用于绑定/限制通用/模板类型参数。
  • Rust特征和带有概念的C ++模板都是单态化的(我知道Rust特征也可以用于动态调度,但这是另外一回事了)。

但据我了解,也存在显着差异。例如,C ++的概念似乎定义了一组必须有效的表达式,而不是列出函数签名。但是那里有很多不同且令人困惑的信息(也许是因为概念仅出现在C ++ 20中?)。这就是为什么我想知道:C ++概念和Rust的特性之间的区别和相似之处到底是什么?

是否存在仅概念或特征提供的功能?例如,Rust的关联类型和const如何?还是用多个特征/概念来界定一个类型?

c++ traits rust c++-concepts

37
推荐指数
1
解决办法
1425
查看次数